刷爆Leetcode Day2

leetcode

  • [6. 和为s的两个数字](#6. 和为s的两个数字)
  • 7.三数之和
  • [8. 四数之和](#8. 四数之和)
  • [9. 长度最小的子数组](#9. 长度最小的子数组)
  • [10. 无重复字符的最长子串](#10. 无重复字符的最长子串)

6. 和为s的两个数字

题目

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        //排序+双指针
        sort(price.begin(),price.end());
        int left=0,right=price.size()-1;
        while(left<right)
        {
            int ret=price[left]+price[right];
            if(ret>target)
            {
                right--;
            }
            else if(ret<target)
            {
                left++;
            }
            else
            {
                //隐式类型转换
                return {price[left],price[right]};
            }
        }
        return {};
    }
};

7.三数之和

三数之和

cpp 复制代码
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        //延续上一题的做法,不过只是target会改变
        //复杂的是这里需要去重也就是三元组之间没有交集(参考集合)
        sort(nums.begin(),nums.end());
        vector<vector<int>> vv;
        int n=nums.size();
        //i++不能在这里,否则会跳过部分元素
        //三元组,因此i最多等于n-3
        for(int i=0;i<n-2;)
        {
            //对于一个已经排好序的数组来说,正整数不需要固定了,因为三数之和一定大于0
            if(nums[i]>0)
            break;
            int left=i+1,right=n-1,target=-nums[i];
            while(left<right)
            {
                int sum = nums[left] + nums[right];
                if(sum>target)
                right--;
                else if(sum<target)
                left++;
                else
                {
                    vv.push_back({nums[left],nums[right],nums[i]});
                    left++;
                    right--;
                    //去重,防止越界如[0,0,0,0,0,0]left会减到-1
                    while(left<right&&nums[left]==nums[left-1])left++;
                    while(left<right&&nums[right]==nums[right+1])right--;
                }
            }
             i++;
            while(i<n-2&&nums[i]==nums[i-1])i++;
        }
        return vv;
    }
};

8. 四数之和

四数之和

cpp 复制代码
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        //延续上一题,不过在此之上要多固定一个
        sort(nums.begin(),nums.end());
        vector<vector<int>> vv;
        int n=nums.size();
        for(int i=0;i<n-3;)
        {
            for(int j=i+1;j<n-2;)
            {
                int left=j+1,right=n-1;
                while(left<right)
                {
                    //数据太大了整形存不下来,[1000000000,1000000000,1000000000,1000000000],用long long
                    //可以先去减target,nums[i]-(long long)这样的话会进行提升做64位的计算,放到后面也会存储不下来
                    long long aim=nums[i]-(long long)target+nums[j]+nums[right]+nums[left];
                    if(aim<0)
                    left++;
                    else if(aim>0)
                    right--;
                    else
                    {
                        vv.push_back({nums[left],nums[right],nums[i],nums[j]});
                        left++;
                        right--;
                        //去重
                        while(left<right&&nums[left]==nums[left-1])left++;
                        while(left<right&&nums[right]==nums[right+1])right--;
                    }
                }
                j++;
                while(j<n-2&&nums[j]==nums[j-1])j++;
            }
            i++;
            while(i<n-3&&nums[i]==nums[i-1])i++;
        }
        return vv;
    }
};

9. 长度最小的子数组

长度最小的子数组

cpp 复制代码
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
    //滑动窗口问题
    //暴力求解:枚举+我们可以通过左下标和右下标划分子数组+遍历子数组求和,O(n^3)
    //滑动窗口是基于"同向双指针"的思想,也就是左右指针朝一个方向移动这是基于求和的单调性
    int left=0,right=-1,n=nums.size(),sum=0,len=100001;
   for(int left = 0, right = 0; right < n; right++)
    {
        //循环进或者循环出,不要用if来判断
        sum += nums[right]; // 进窗⼝ 
        while(sum >= target) // 判断 
        {
            len = len>right-left+1?right-left+1:len;// 更新结果 
            sum -= nums[left++]; // 出窗⼝ 
        }
    }
    //注意len最大为100000,可能整个数组求和都小于target,此时判断len是否等于100001来判断村子不符合条件的子数组
     return len == 100001 ? 0 : len;
    }
};

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

无重复字符的最长子串

cpp 复制代码
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //滑动窗口问题
        //我们需要一个哈希表来映射相同元素以便可以去重
        //对于一个重复子串,我们很容易想到除非我们跳过重复元素,否则重复子串的子串一定是减少的
        //通过整形数组实现哈希表
        int n=s.size();
        int len=0;
        // 创建⼀个哈希表,统计频次
        int hash[96] = { 0 };
        for (int left=0,right = 0; right < n; right++)
        { 
            //映射
            char gap=31;
             // 寻找结束为⽌ 
            hash[s[right]-31]++; // 统计字符出现的频次 
            while (hash[s[right]-31] > 1) // 如果出现重复的
            {
                hash[s[left]-31]--;
                left++;
            } 
            // 如果没有重复,就更新 ret 
            len=len>right-left+1?len:right-left+1;
        }
        return len;
    }
};
相关推荐
charlie1145141915 分钟前
C++ STL CookBook
开发语言·c++·stl·c++20
Lenyiin12 分钟前
01.02、判定是否互为字符重排
算法·leetcode
小林熬夜学编程16 分钟前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
倔强的石头10627 分钟前
【C++指南】类和对象(九):内部类
开发语言·c++
鸽鸽程序猿27 分钟前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd27 分钟前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo61731 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v36 分钟前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A2 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
古希腊掌管学习的神2 小时前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵