• 两数之和 三数之和【基础算法精讲 01】


    灵神算法基础算法精讲[01] : 

    两数之和 三数之和【基础算法精讲 01】_哔哩哔哩_bilibili

    167.两数之和 II - 输入有序数组

    链接 : 

    力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

    思路 : 

    1. 采用双指针的思想,因为给出的数组是有序的,n  = len(numbers),定 l = 0,r = n-1;
    2. 如果s = numbers[l] + numbers[r]  > target , 那么s要变小,则r--;
    3. 如果s = numbers[l] + numbers[r]  < target , 那么s要变大,则l++;
    4. 如果s = numbers[l] + numbers[r]  = target , 那么就得到结果了,则返回[l+1,r+1]即可;

    代码(python):

    1. class Solution:
    2. def twoSum(self, numbers: List[int], target: int) -> List[int]:
    3. l = 0
    4. r = len(numbers)-1
    5. while True:
    6. s = numbers[l] + numbers[r]
    7. if s==target:
    8. break
    9. if s>target:
    10. r -= 1
    11. else :
    12. l += 1
    13. return [l+1,r+1]

    代码(c++):

    1. class Solution {
    2. public:
    3. vector<int> twoSum(vector<int>& numbers, int target) {
    4. int l=0,r=numbers.size()-1;
    5. while(true){
    6. int s = numbers[l]+numbers[r];
    7. if(s==target) break;
    8. if(s>target) r--;
    9. else l++;
    10. }
    11. return {l+1,r+1};
    12. }
    13. };

    三数之和

    链接 : 

    三数之和

    思路 :

    假设满足条件的三个数的下标分别为i , j, k,且默认i

    先对数组进行排序,方便后面的操作

    对i进行枚举,然后就是一个双指针的问题,令x=nums[i] , j=i+1 , k=n-1 ; 令 s = x + nums[j] + nums[k] , 剩下的就可以参考前一题中的思路:

    1.如果s > 0  :  k--;

    2.如果s<0  : j++

    3.如果s=0 : 添加到结果中;

    去重 : 分别对i,j,k去重;

    优化 : 如果相邻的三数之和>0,那么就可以直接break了,因为后面的只会加大

    如果nums[i]+nums[n-1]+nums[n-2]<0,那么就continue,因为这是以i为起点的情况下s的最大值,如果小于0,那么直接continue,跳到下一个 i 上;

    代码( python ):

    1. class Solution:
    2. def threeSum(self, nums: List[int]) -> List[List[int]]:
    3. nums.sort()
    4. # 排序
    5. # i
    6. ans = []
    7. n = len(nums)
    8. for i in range(n-2):
    9. x = nums[i]
    10. if i>0 and x==nums[i-1]:# 对x去重
    11. continue
    12. if x+nums[i+1]+nums[i+2]>0: # 优化
    13. break
    14. if x+nums[-2]+nums[-1]<0: # 优化
    15. continue
    16. j = i + 1
    17. k = n - 1
    18. while j < k:
    19. s = x + nums[j] + nums[k]
    20. if s>0:
    21. k -= 1
    22. elif s < 0:
    23. j += 1
    24. else:
    25. ans.append([x,nums[j],nums[k]])
    26. j += 1
    27. while jand nums[j]==nums[j-1]:# 对j去重
    28. j+=1
    29. k-=1
    30. while jand nums[k]==nums[k+1]:# 对k去重
    31. k-=1
    32. return ans

    代码( c++ ) : 

    1. class Solution {
    2. public:
    3. vectorint>> threeSum(vector<int>& nums) {
    4. int n = nums.size();
    5. vectorint>> ans;
    6. sort(nums.begin(),nums.end());
    7. for(int i=0;i-2;i++)
    8. {
    9. int x = nums[i];
    10. if(x+nums[i+1]+nums[i+2] > 0) return ans;//如果三数和最小值大于0,那么直接返回
    11. if(x+nums[n-1]+nums[n-2]<0) continue;
    12. // 对a去重
    13. if(i>0 && nums[i] == nums[i-1]) continue;
    14. int left = i+1;
    15. int right = n-1;
    16. while(right>left)
    17. {
    18. int x = nums[i] + nums[left] + nums[right];
    19. if(x > 0) right--;
    20. else if(x < 0) left++;
    21. else
    22. {
    23. ans.push_back(vector<int>{nums[i],nums[left],nums[right]});
    24. while(left-1]) right--;
    25. while(left < right && nums[left] == nums[left+1]) left ++;
    26. left++;
    27. right--;
    28. }
    29. }
    30. }
    31. return ans;
    32. }
    33. };

    习题 : 


    最接近的三数之和

    链接:

     https://leetcode.cn/problems/3sum-closest/

    思路 :  

    与三数之和类似,详情请看代码 : 

    1. class Solution {
    2. public:
    3. int threeSumClosest(vector<int>& nums, int target) {
    4. sort(nums.begin() , nums.end());
    5. int n = nums.size(),mi = 1e5+7,ans = 0,s;
    6. for(int i=0;i-2;i++){
    7. int x = nums[i];
    8. if(i>0 && x==nums[i-1]) continue;// 优化一
    9. s = x + nums[i + 1] + nums[i + 2];
    10. if (s>target) { //优化二
    11. if (s-target
    12. break;
    13. }
    14. s = x + nums[n - 2] + nums[n - 1];
    15. if (s < target) { // 优化三
    16. if (target-s
    17. mi = target-s;
    18. ans = s;
    19. }
    20. continue;
    21. }
    22. int j=i+1,k=n-1;
    23. while(j
    24. int s = nums[j] + nums[k] + x;
    25. if(s==target) return s;
    26. else if(s>target){
    27. if(s-target < mi){
    28. mi = s-target;
    29. ans = s;
    30. }
    31. k--;
    32. }
    33. else if(s
    34. if(target-s < mi){
    35. mi = target - s;
    36. ans = s;
    37. }
    38. j++;
    39. }
    40. }
    41. }
    42. return ans;
    43. }
    44. };

    四数之和 : 

    链接 : 

    https://leetcode.cn/problems/4sum/description/

    思路 : 和之前思路一样,双指针即可,加上去重和剪枝即可!!!

    代码 : 

    1. class Solution {
    2. public List> fourSum(int[] nums, int target) {
    3. Arrays.sort(nums);
    4. List> ans = new ArrayList<>();
    5. int n = nums.length;
    6. for(int a=0;a3;a++){//枚举第一个数
    7. long x = nums[a];
    8. if(a>0 && x==nums[a-1]) continue;//优化一
    9. if(x+nums[a+1]+nums[a+2]+nums[a+3]>target) break;//优化二
    10. if(x+nums[n-3]+nums[n-2]+nums[n-1]continue; // 三
    11. for(int b=a+1;b2;b++){
    12. long y = nums[b];
    13. if(b>a+1 && y==nums[b-1]) continue;//四
    14. if(x+y+nums[b+1]+nums[b+2]>target) break;//五
    15. if(x+y+nums[n-2]+nums[n-1]continue;//六
    16. int c = b+1,d=n-1;
    17. while(c
    18. long s = x+y+nums[c]+nums[d];
    19. if(s>target) d--;
    20. else if(s
    21. else {
    22. ans.add(List.of((int)x,(int)y,nums[c],nums[d]));
    23. for(c++;c1];c++);
    24. for(d--;d>c&&nums[d]==nums[d+1];d--);
    25. }
    26. }
    27. }
    28. }
    29. return ans;
    30. }
    31. }

     统计和小于目标的下标对数目 : 

    链接 : 
    链接icon-default.png?t=N7T8https://leetcode.cn/problems/count-pairs-whose-sum-is-less-than-target/

     思路 : 

    双指针

    代码 : 

    1. class Solution {
    2. public:
    3. int countPairs(vector<int>& nums, int target) {
    4. int ans = 0;
    5. int n = nums.size();
    6. sort(nums.begin(),nums.end());
    7. int i=0,j=n-1;
    8. while(i
    9. int s = nums[i]+nums[j];
    10. if(s
    11. ans += j-i;
    12. i++;
    13. }else {
    14. j--;
    15. }
    16. }
    17. return ans;
    18. }
    19. };

    有效三角形的个数 :

    链接 : 

    有效三角形的个数

    思路 : 

    双指针

    代码 : 

    1. class Solution {
    2. public:
    3. int triangleNumber(vector<int> &nums) {
    4. sort(nums.begin(), nums.end());
    5. int ans = 0;
    6. for (int k = 2; k < nums.size(); k++) {
    7. int c = nums[k];
    8. int i = 0; // a=nums[i]
    9. int j = k - 1; // b=nums[j]
    10. while (i < j) {
    11. if (nums[i] + nums[j] > c) {
    12. // 由于 nums 已经从小到大排序
    13. // nums[i]+nums[j] > c 同时意味着:
    14. // nums[i+1]+nums[j] > c
    15. // nums[i+2]+nums[j] > c
    16. // ...
    17. // nums[j-1]+nums[j] > c
    18. // 从 i 到 j-1 一共 j-i 个
    19. ans += j - i;
    20. j--;
    21. } else {
    22. // 由于 nums 已经从小到大排序
    23. // nums[i]+nums[j] <= c 同时意味着
    24. // nums[i]+nums[j-1] <= c
    25. // ...
    26. // nums[i]+nums[i+1] <= c
    27. // 所以在后续的循环中,nums[i] 不可能作为三角形的边长,没有用了
    28. i++;
    29. }
    30. }
    31. }
    32. return ans;
    33. }
    34. };

  • 相关阅读:
    清华陆向谦教授提到的纽约时报的一篇文章-探讨学历贬值
    面试题-React(十六):理解Redux及其工作原理
    java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发
    JavaScript的位操作符你知道吗?
    vue之表单输入绑定
    C语言中的 int main(int argc,char const *argv[])是什么意思?
    多电商平台订单整合,库存同步ERP系统,为何不用电商API对接?
    数字源表如何助力miniled光电性能测试
    【冰糖R语言】实现贝叶斯优化 rBayesianOptimization
    使用 PHP、PDO 和 MySQL 的 CRUD 应用程序
  • 原文地址:https://blog.csdn.net/ros275229/article/details/133131907