当前位置: 首页 > news >正文

LeetCode 15. 3Sum; 16. 3Sum Closest; 259. 3Sum Smaller; 18. 4Sum

15. 3Sum

Two Sum 的 follow up

Two Sum 使用hashtable做到O(n)时间复杂度

所以看到这道题,第一想法是固定一个元素,剩下的用 Two Sum 处理。但是由于这道题有重复元素存在,最后去重会TLE,因此不能这样做。

在一个有序数组里寻找加和为给定值的两个元素,我们可以使用 Two Pointers 从两侧向中间来寻找。

对于这道题,我们可以先对数组进行排序,固定一个数nums[i],用 Two Pointers 寻找加和等于 -nums[i] 的两个数。每次两个pointer都跳过重复的元素,固定的nums[i]也跳过重复的元素,这样最后答案里所有的解都是唯一的了。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        for (int i=0;i<nums.size();++i){
            int target= -nums[i];
            int low=i+1, high=nums.size()-1;
            while (low<high){
                int sum=nums[low]+nums[high];
                if (sum<target) ++low;
                else if (sum>target) --high;
                else{ 
                    vector<int> tri({nums[i],nums[low],nums[high]});
                    res.push_back(tri);
                    
                    //skip the same value as nums[low]
                    while (low<high && nums[low]==tri[1]) ++low;
                    
                    //skip the same value as nums[high]
                    while (low<high && nums[high]==tri[2]) --high;
                }
            }
            //skip the same value as nums[i]
            while (i+1<nums.size() && nums[i+1]==nums[i])
                ++i;
        }
        return res;
    }
};

 

16. 3Sum Closest

和 3 Sum 几乎一模一样,复习一下。

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        if (nums.size()<3) return 0;
        int res=nums[0]+nums[1]+nums[2];
        sort(nums.begin(),nums.end());
        
        for (int i=0;i<nums.size();++i){
            if (i>=1 && nums[i]==nums[i-1]) continue;
            int low=i+1, high=nums.size()-1;
            
            while (low<high){
                int curSum=nums[i]+nums[low]+nums[high];
                if (curSum==target) return curSum;
                if (abs(curSum-target)<abs(res-target))
                    res = curSum;
                if (curSum<target) ++low;
                else if (curSum>target) --high;
            }
        }
        return res;
    }
};

 

259. 3Sum Smaller

curSum<target 时,low不变,high从high到low+1都是可行的,所以+=high-low。

class Solution {
public:
    int threeSumSmaller(vector<int>& nums, int target) {
        int cnt=0;
        sort(nums.begin(),nums.end());
        
        for (int i=0;i<nums.size();++i){
            int low=i+1, high=nums.size()-1;
            while (low<high){
                int curSum=nums[i]+nums[low]+nums[high];
                if (curSum<target){
                    cnt += high-low; // the third num can be any element in (low,high]
                    ++low;
                }else --high;
            }
        }
        return cnt;
    }
};

 

18. 4Sum

还是一样的套路,把之前的写法跟精简了一下:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        for (int i=0;i<nums.size();++i){
            if (i>0 && nums[i]==nums[i-1]) continue;
            for (int j=i+1;j<nums.size();++j){
                if (j>i+1 && nums[j]==nums[j-1]) continue;
                int low=j+1, high=nums.size()-1;
                while (low<high){
                    int sum=nums[i]+nums[j]+nums[low]+nums[high];
                    if (sum==target){
                        res.push_back({nums[i],nums[j],nums[low],nums[high]});
                        ++low; --high;
                        while (low<high && nums[low]==nums[low-1]) ++low;
                        while (low<high && nums[high]==nums[high+1]) --high;
                    }else if (sum<target) ++low;
                    else --high;
                }
            }
        }
        return res;
    }
};

 

转载于:https://www.cnblogs.com/hankunyan/p/9552049.html

相关文章:

  • 蓝牙4.0 For IOS
  • gpio_direction_output和gpio_set_value
  • JVM系列三:JVM运行时数据区
  • web安全Wargame—Natas解题思路(1-26)
  • jQuery插件开发详细教程
  • Vue.js从Virtual DOM映射到真实DOM的过程
  • screen终端命令使用
  • 德国精品软件   cFosSpeed 网络优化软件
  • 数据分析师完整的知识结构
  • 结构体中定义函数指针
  • 人工智能与勒索病毒较量,你猜最后谁能赢了?
  • 行为型设计模式之命令模式(Command)
  • WPF DataGrid 每行ComboBox 内容不同的设置方法
  • 十五天精通WCF——第六天 你必须要了解的3种通信模式
  • 程序员如何成为架构师
  • Google 是如何开发 Web 框架的
  • [笔记] php常见简单功能及函数
  • 2017年终总结、随想
  • django开发-定时任务的使用
  • es6要点
  • export和import的用法总结
  • fetch 从初识到应用
  • happypack两次报错的问题
  • Javascript弹出层-初探
  • Java-详解HashMap
  • Java新版本的开发已正式进入轨道,版本号18.3
  • JS+CSS实现数字滚动
  • Laravel核心解读--Facades
  • magento2项目上线注意事项
  • SSH 免密登录
  • Swoft 源码剖析 - 代码自动更新机制
  • v-if和v-for连用出现的问题
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 大主子表关联的性能优化方法
  • 汉诺塔算法
  • 来,膜拜下android roadmap,强大的执行力
  • 力扣(LeetCode)22
  • 利用DataURL技术在网页上显示图片
  • 嵌入式文件系统
  • 小李飞刀:SQL题目刷起来!
  • 正则表达式
  • mysql面试题分组并合并列
  • Spring第一个helloWorld
  • 第二十章:异步和文件I/O.(二十三)
  • #if 1...#endif
  • #LLM入门|Prompt#3.3_存储_Memory
  • #图像处理
  • $.ajax()方法详解
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (9)目标检测_SSD的原理
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (ZT)出版业改革:该死的死,该生的生
  • (差分)胡桃爱原石
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统