做题

简介: 学习编程语言的过程要记得刷题哦


最长回文子串

解题思路:中心扩散法

中心扩散法

其实,我们知道,对于回文子串来说,是对称的。也就是说,从中心开始,往左扩散,往右扩散,一直去比较左右两边,如果一样,就再去往左扩散,往后扩散,直到结束,如果出现不相等的情况,那就说明不是回文子串。我们来举个例子:

接下来的问题是:怎么用代码去实现这个过程。

代码实现

我们遍历这个字符串的每一个字符,第一步,先找到上面的中间相同的a,先往左边找,看看有没有相同的,有的话就往左扩散,找到不相同的或者尽头,同理往右边扩散。第二步就是往左右两边同时对比是否相同:

char * longestPalindrome(char * s){
    int len = strlen(s);
    if(len==0)
    {
         return NULL;
    }
    //最大长度
    int maxLenth = 1;
    //起始下标
    int maxIndex = 0;
    for(int i = 0;i<len;i++)
    {
        //当前位置
        int curIndex = i;
        //左边
        int left = i;
        //右边
        int right = i;
        while(left!=0)
        {
            //相同往左边扩散
            if(s[left-1]==s[curIndex])
            {
                --left;
            }
            else
            {
                break;
            }
        }
        while(right!=len-1)
        {
            //相同往右边扩散
            if(s[right+1] == s[curIndex])
            {
                right++;
            }
            else
            {
                break;
            }
        }
        //往左右两边扩散
        while(left!=0&&right!=len-1)
        {
            if(s[left-1]==s[right+1])
            {
                left--;
                right++;
            }
            else
            {
                break;
            }
        }
        //更新变量
        if((right-left+1)>maxLenth)
        {
            maxLenth = right-left+1;
            maxIndex = left;
        }
    }
    char*str = (char*)malloc(sizeof(char)*(maxLenth+1));
    if(NULL == str)
    {
        return;
    }
    int j = 0;
    for(int i = maxIndex;i<=maxIndex+maxLenth-1;i++)
    {
        str[j++] = s[i];
    }
    str[j] = '\0';
    return str;
}

至此,我们顺利通过了这道题。

无重复字符的最长子串

这道题可以用数组哈希和滑动来进行解决。

定义left和right(初始化为0)这两个变量来记录左右的边界,让字符串中的每一个元素作为数组hash(初始化为0)的下标,我们以s[right]作为判断的条件,第一次出现就hash[s[right]]++,同时右边界往右走,既right++,如果出现重复,此时的hash对应的下标已经不是0了,我们就hash[s[left]]–,同时左边界left也要进行更新,left++.

定义count去记录right-left的最大值。接下来就是代码的实现了:

网络异常,图片无法展示
|

int lengthOfLongestSubstring(char * s){
    char hash[128];
    memset(hash,0,sizeof(hash));
    int left = 0,right = 0,count = 0;
    while(s[right])
    {
        if(hash[s[right]])
        {
            hash[s[left]]--;
            ++left;
        }
        else
        {
            hash[s[right]]++;
            ++right;
        }
        //更新count
        count  =count<(right-left)?(right-left):count;
    }
    return count;
}

数组中的第 k 大的数字

解题思路:利用堆的应用,topK问题。

题目是要找数组的第K大的数字,我们利用K个数建成一个小堆(向下调整算法)。剩下的数N-k个数我们去和堆顶进行比较,因为是要找第K大的数字,如果比堆顶大,我们就把堆顶替换,同时进行向下调整,最终堆顶就是第K大的数。

void Swap(int*p1,int*p2)
{
    int tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
}
void AdjustDown(int*a,int n,int parent)
{
    int minChild = 2*parent+1;
    while(minChild<n)
    {
        if(minChild+1<n&&a[minChild+1]<a[minChild])
        {
            minChild++;
        }
        if(a[minChild]<a[parent])
        {
            Swap(&a[minChild],&a[parent]);
            parent = minChild;
            minChild = 2*parent+1;
        }
        else
        {
            break;
        }
    }
}
int findKthLargest(int* nums, int numsSize, int k){
    int* minHeap = (int*)malloc(sizeof(int)*k);
    if(minHeap == NULL)
    {
        exit(-1);
    } 
    else
    {
        for(int i = 0;i<k;i++)
        {
            minHeap[i] = nums[i];
        }
        for(int j = (k-1-1)/2;j>=0;j--)
        {
            AdjustDown(minHeap,k,j);
        }
        for(int i = k;i<numsSize;i++)
        {
            if(nums[i]>minHeap[0])
           {
              minHeap[0] = nums[i];
              AdjustDown(minHeap,k,0);
           }
        }
    }
    int ret = minHeap[0];
    free(minHeap);
    return ret;
}

字符串转换整数 (atoi)

一个非常有意思的题目,说难并不算难,但是要求还是蛮多的,注意看要求写代码就行了:

enum Status
{
  VALID,
  INVALID
}sta = INVALID;//默认非法
int myAtoi(char * s){
    long long  ret = 0;
  int flag = 1;
  assert(s);
  if (*s == '\0')
  {
    return 0;
  }
  while (isspace(*s))
  {
    s++;
  }
  if (*s == '+')
  {
    flag = 1;
    s++;
  }
  else if (*s == '-')
  {
    flag = -1;
    s++;
  }
  while (*s)
  {
    if (isdigit(*s))
    {
      //越界
      ret = ret * 10 + flag * (*s - '0');
      if (ret > INT_MAX)
      {
        return INT_MAX;
      }
            if(ret<INT_MIN)
            {
                return INT_MIN;
            }
    }
    else
    {
      return (int)ret;
    }
    s++;
  }
  if (*s == '\0')
  {
    sta = VALID;
  }
  return (int)ret;
}




相关文章
|
人工智能 架构师 NoSQL
24岁程序媛,二战考研失利、三无人员 ==> 最佳新人、优秀个人,讲讲我的技术成长之路
能力、格局、谋略、远见、耐心。灵魂的欲望是命运的先知,希望永远自信、洒脱、松弛、明媚、张扬;追随自己的内心、以喜欢的方式、往正确的方向前行,永远在路上,我甘之如饴! 持续精进Java领域相关技术,包括微服务、高并发、高可用、分布式、集群等等;希望能接触到更多更大的优质项目,逐渐成长为一名具备全栈思维的架构师,既能深入理解底层技术,又能把控全局架构;抽时间了解学习Go语言、人工智能、大模型等领域。 在探索中明晰后续的发展方向,形成自己的一套体系,成为主管、管理层乃至更高,不希望自己的上限只是程序员。
|
10月前
|
人工智能 开发者
3步,0代码!一键部署DeepSeek-V3、DeepSeek-R1
阿里云PAI Model Gallery支持一键部署DeepSeek-V3、DeepSeek-R1模型,用户可在平台上零代码实现从训练到部署再到推理的全过程,简化开发流程。通过登录PAI控制台,选择Model Gallery,找到并部署所需模型,如“DeepSeek-R1-Distill-Qwen-7B”,享受高效便捷的AI应用体验。部署成功后可获取调用信息,快速集成到业务中。
597 13
|
数据处理 Python
【Python】解决tqdm ‘module‘ object is not callable
在使用tqdm库时遇到的“'module' object is not callable”错误,并给出了正确的导入方式以及一些使用tqdm的常见示例。
602 1
|
存储 Oracle 关系型数据库
PolarDB-X 存储引擎核心技术 | Lizard B+tree 优化
PolarDB-X 分布式数据库,采用集中式和分布式一体化的架构,为了能够灵活应对混合负载业务,作为数据存储的 Data Node 节点采用了多种数据结构,其中使用行存的结构来提供在线事务处理能力,作为 100% 兼容 MySQL 生态的数据库,DN 在 InnoDB 的存储结构基础上,进行了深度优化,大幅提高了数据访问的效率。
7926 25
|
机器学习/深度学习 人工智能 自然语言处理
AIGC-基于EAS服务快速部署一个AI视频生成
AIGC-基于EAS服务快速部署一个AI视频生成
|
容器
Flutter下拉刷新上拉加载的简单实现方式一
Flutter下拉刷新上拉加载的简单实现方式一
381 2
|
NoSQL 关系型数据库 MongoDB
实时计算 Flink版产品使用合集之实现多张表的同步如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
JSON API 数据格式
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(2)
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(2)
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(2)
|
安全 Java 关系型数据库
保险业务管理系统|基于JavaWeb保险业务管理系统的设计与实现(一)
保险业务管理系统|基于JavaWeb保险业务管理系统的设计与实现
357 1
|
JavaScript
重排和重绘的区别,什么情况下会触发这两种情况
重排和重绘的区别,什么情况下会触发这两种情况
527 0