LeetCode刷题-题目3、4

本文介绍了两种使用双指针解决字符串问题和优化数组排序寻找中位数的方法。对于无重复字符的最长子串问题,通过双指针技巧找到左边界和右边界,动态更新最长子串长度。而对于寻找两个正序数组中位数的挑战,通过合并数组并排序的原始方法被改进为更高效的双指针策略,确定中位数位置。这些解题策略展示了算法优化的重要性。
摘要由CSDN通过智能技术生成

3.无重复字符的最长子串

解题:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len=0;
        int slow=0 ,fast=0; //双指针思想,slow为左边界,fast为右边界
        if(s.length()<=0) return 0;
        while(fast<s.length()){
            for(int i=slow;i<fast;i++){
                if(s[i]==s[fast]){
                    slow=i+1; //slow指针指向匹配相同的字符的下一个位置
                    break;
                }
            }
            len=max(len,fast-slow+1); //取每次的最大值
            fast++;
        }
        return len;
    }
};

通过结果:

 4.寻找两个正序数组的中位数

 解题:

class Solution {
public:
    void sort(int nums[],int len){   //采用简单插入排序
        int temp;
        for(int i=1;i< len;i++) {
            for(int j=i-1;j>=0;j--){
                if(nums[j+1]<nums[j]) {  //将大的往后面一直传,也就是小的一直往前传
                    temp=nums[j];
                    nums[j]=nums[j+1];
                    nums[j+1]=temp;
                }
                else break;
            }
        }
}
    
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len=nums1.size()+nums2.size(); 
        int nums3[len];
     
        for(int i=0;i<nums1.size();i++){
            nums3[i]=nums1[i];
        }
        for(int i=0;i<nums2.size();i++){
            nums3[nums1.size()+i]=nums2[i];
        }
        sort(nums3,len);
        return (len) % 2 == 0 ? (nums3[(len/2)-1]+nums3[len/2]) / 2.0 : nums3[len/2];
    }
};

注:思路很粗暴,就是先把两个数组合并起来,然后进行排序,再取中位数。排序采用的插入排序,时间复杂度为O(n*n),这个解决方案粗暴又耗时。

通过结果:

代码优化

 不一定要重新做一个数组,其实我们只要确定中位数的位置即可,也就是比如nums1长度为2,nums2长度为3,那么中位数的位置就是第三个,也就是5个数字中第3个最大的数。我们只需要确定第三个最大数是多少即可

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len1=nums1.size();
        int len2=nums2.size();
        int len3=len1+len2;
        int i=0,j=0,slow=0,fast=0; //i,j分别代表nums1和nums2的指针

        for(int k=0;k<=len3/2;k++){
            slow=fast;
            //i小于nums1长度,说明nums1中还没有被读完,且 i大于j或者是nums2已经被读完了
            if( i<len1 && (j>=len2 || nums1[i]<nums2[j]) ){
                fast=nums1[i];
                i++;
            }
            //其他情况就是i被读完了但此时还没到达中位数的位置、或者nums2小于nums1
            else{
                fast=nums2[j];
                j++;
            }
        }
        return (len3)%2 == 0?(fast+slow)/2.0 : fast;
    }
};

运行结果:

ps:如果把最后的return修改:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值