leetcode 228.汇总区间(C/C++/java/python)

PS:算法并非原创,仅作个人学习记录使用,侵删

题目描述
在这里插入图片描述

算法分析
个人的算法思路是:遍历一遍数组,每次根据是否连续进行数组分割和结果记录。
后来在看了各类算法博客之后,大致上都是这种思路,但是可以采用“双指针”方法使得算法更加清晰。

代码实现
【C】

/*
该算法实现使用了双指针方法,分别指向连续区间的起始位置和终止位置
*/
char** summaryRanges(int* nums, int numsSize, int* returnSize) {
    //nums:待处理数组,numsSize:待处理数组长度,returnSize:返回的数组长度
    char** ret = (char**)malloc(sizeof(char*) * numsSize);//返回的字符数组,动态分配内存
    //变量初始化
    *returnSize = 0;
    int i = 0;
    int low = 0;//低指针
    int high = 0;//高指针
    //数组遍历
    while (i < numsSize) {
        low = i;//记录连续区间的起始位置
        i++;
        //如果一直连续,则遍历指针一直移动
        while (i < numsSize && nums[i] == nums[i - 1] + 1) {
            i++;
        }
        //连续区间结束,更新结束位置的指针
        high = i - 1;
        //构造已有的连续空间结果
        char* temp = (char*)malloc(sizeof(char) * 25);//临时字符数组
        sprintf(temp, "%d", nums[low]);//将nums[low](起始位置的值)输出到指定字符串中
        /*
        int sprintf(char *buffer,const char *format,[argument]…);
        sprintf函数的功能与printf函数的功能基本一样,只是它把结果输出到指定的字符串中
            buffer:char型指针,指向将要写入的字符串的缓冲区。
            format:格式化字符串。
            [argument]...:可选参数,可以是任何类型的数据。
        */
        if (low < high) {//如果连续区间的长度大于一
            sprintf(temp + strlen(temp), "->");//加上“->”
            sprintf(temp + strlen(temp), "%d", nums[high]);//加上终止位置的值
        }
        ret[(*returnSize)++] = temp;//ret数组中加入temp结果,returnSize++
    }
    return ret;//返回字符数组结果
}

C语言参考网址
【C++】

/*
C++解法中,同样用到了双指针的思想,只是终止位置的指针用遍历指针替代,导致最后一个连续区间的处理情况有些复杂
*/
class Solution {
public:
    vector<string> summaryRanges(vector<int>& nums){
        vector<string> res;//res格式为vector,方便添加元素
        int n=nums.size();//待处理数组长度
        //处理元素的数据类型,转化为long long型
        for(int i=0;i<n;i++){
            nums[i]=(long long)nums[i];
        }
        //特殊情况:数组长度为0,不需要做处理
        if(0==n){
            return res;
        }
        string tmp=to_string(nums[0]);//tmp用于存储当前遍历到的连续区间的临时结果,当前字符串存入起始位置的元素值
        int start=0;//开始位置
        //遍历数组
        for(int i=1;i<n;i++){
            //如果区间不连续,需要进行处理
            if(nums[i]!=nums[i-1]+1){
                if(i==start+1){//不连续区间长度为1时
                    res.push_back(tmp);//结果中添加单个元素值
                    //vector.push_back(),在vector结构中添加元素
                    start=i;//更新起始位置,继续后续遍历
                    tmp=to_string(nums[i]);//tmp起点变换
                }
                else{//不连续区间长度大于1时,
                    tmp+="->";
                    tmp+=to_string(nums[i-1]);
                    //tmp构造成功
                    res.push_back(tmp);//添加进结果
                    start=i;//更新起始位置
                    tmp=to_string(nums[i]);//tmp起点变换
                }
            }
            //如果一直连续,i++
        }
        //遍历完成之后,i=n-1,为了弥补双指针中终止位置的缺失,需要考虑最后一个区间
        if(start==n-1){//如果xx~n-2是一个连续数组,之后start=n-1,说明最后一个连续区间长度等于1
            res.push_back(tmp);//结果中只添加单个元素值
        }
        else{//如果最后一个连续区间起始位置不是n-1,说明连续区间长度大于1
            tmp+="->";
            tmp+=to_string(nums[n-1]);
            res.push_back(tmp);
        }
        return res;//返回结果
    }
};

C++参考网址
【java】

/*
java采用的是直接遍历的思路,但是没有使用典型的双指针方法。
它在每个区间开始,给出临时结果,写入起始位置,之后不断向前遍历,如果最终停下来的位置和开始遍历的位置不同,进行临时结果构造,否则直接写入。由此进行一次遍历得出所有结果
*/
class Solution {
   public List<String> summaryRanges(int[] nums) {
        List<String> list = new ArrayList<>();//结果列表,初始为空
        int pos = 0;//用于遍历
        while (pos < nums.length) {//进行数组遍历
            StringBuilder it = new StringBuilder(""+nums[pos]);//it存储当前区间的结果,初始时存入起始位置元素值
            int temp = pos;//起始位置
            while (pos + 1 < nums.length && nums[pos + 1] == nums[pos] + 1)//一直连续
                pos++;//一直向前遍历

            if (pos != temp)//如果起始位置和遍历位置不相同,说明连续区间长度大于1
                it.append("->").append(nums[pos]);//it临时结果中添加"->终止位置元素值"
            list.add(it.toString());//在结果列表中加入
            pos++;//继续遍历
        }
        return list;
    }
}

Java参考网址
【python】

#
#python的解题思想和C++类似。
#不同的是,它不使用遍历指针作为终止位置指针,而是用一个连续区间长度变量和起始指针相结合得出终止位置指针。
#由于终止位置指针的缺失,同样需要对最后一个连续区间进行另外的处理
#
class Solution:
    def summaryRanges(self, nums):
        """
        :type nums: List[int]
        :rtype: List[str]
        """
        n=len(nums)
        res=[]#结果列表,初始为空
        count=0#连续区间长度
        #特殊情况,数组长度为0,不需要处理
        if n==0:
            return res
        #数组长度为1,结果列表只有一个
        elif n==1:
            temp=str(nums[0])
            res.append(temp)#append()添加列表元素
            return res
       #数组长度大于1
        else:
            aa=nums[0]#连续区间起始位置
            temp=str(nums[0])#temp存储当前区间结果
            for i in range(1,n):#遍历数组
                if nums[i]-nums[i-1]==1:#如果依然是连续区间
                    count += 1#连续区间长度+1
                else:#出现不连续区间
                    if count==0:#连续区间长度为1
                        res.append(temp)
                        aa=nums[i]#更细起始位置
                        temp=str(nums[i])
                    else:#连续区间长度大于1
                    	#构造连续区间对应的结果
                        temp+="->"
                        temp+=str(aa+count)#此处说明了count的作用
                        res.append(temp)#将连续区间结果添加进结果列表
                        aa=nums[i]#更新起始位置
                        count=0#更新连续区间长度
                        temp=str(nums[i])#temp结果更新
            if count==0:#最后一个连续区间,如果长度为1
                res.append(temp)
            else:#最后一个连续区间,长度大于1
                temp+="->"
                temp+=str(aa+count)
                res.append(temp)
            return res;

python参考网址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值