• 【算法挨揍日记】day04——15. 三数之和、18. 四数之和


     

     15. 三数之和

    15. 三数之和icon-default.png?t=N7T8https://leetcode.cn/problems/3sum/

    题目描述:

    给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

    注意:答案中不可以包含重复的三元组

    解题思路:

    我们先来看看题目:题目要求a+b+c=0,并且a、b、c三个数的下标各不相同,并且返回所有的可能性,并且要去重

     我们首先可以确定一下大体思路:sort排序(有序),有序可以被双指针或者二分来运用,这里我们使用排序+双指针

    我们这里是三数之和,我们可以确定一个cur下标来遍历数组,一次一个数,然后问题就变成了剩下的数组的两数之和的问题!

    我们两数之和就可以就可以运用双指针来降时间复杂度,left和right从两边到中间

    这里比较考察大家的是left和right的边界问题,这里非常容易越界!!!

    我们来结合本题的部分代码来理解

    我们整个红色区域可以划分为[begin,right](这里就不用left和right避免混乱,这里的begin代表红色的第一个,end是红色区域的最后一个的下一个),我们正常来说left0的,但是我们这边下标访问涉及到left+1和right-1,所以left需要比end少一,也就是让left+1最大到end-1的位置,同理right>1

    解题代码:

    1. class Solution {
    2. public:
    3. vectorint>> threeSum(vector<int>& nums) {
    4. sort(nums.begin(), nums.end());
    5. vectorint>> nnums;
    6. int size = nums.size();
    7. int cur = 0;
    8. while (cur < size - 1)
    9. {
    10. int left = cur + 1;
    11. int right = size - 1;
    12. int a = (-1) * nums[cur];//找到两数之和为a的两个值
    13. while (left < right)
    14. {
    15. if (nums[left] + nums[right] == a)
    16. {
    17. nnums.push_back({ nums[cur],nums[left],nums[right] });
    18. while (right > 1 && nums[right] == nums[right - 1])
    19. right--;
    20. right--;
    21. }
    22. else if (nums[left] + nums[right] > a)
    23. {
    24. while (right > 1 && nums[right] == nums[right - 1])
    25. right--;
    26. right--;
    27. }
    28. else if (nums[left] + nums[right] < a)
    29. {
    30. while (left-1&&nums[left] == nums[left + 1])
    31. left++;
    32. left++;
    33. }
    34. }
    35. while (cur-1&&nums[cur] == nums[cur + 1])
    36. cur++;
    37. cur++;
    38. }
    39. return nnums;
    40. }
    41. };

    18. 四数之和

    18. 四数之和icon-default.png?t=N7T8https://leetcode.cn/problems/4sum/

     题目描述:

    给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

    • 0 <= a, b, c, d < n
    • abc 和 d 互不相同
    • nums[a] + nums[b] + nums[c] + nums[d] == target

    你可以按 任意顺序 返回答案 。

    解题思路:

    本题与上题一样,就是在三数之和的基础上外面再套一层

    解题代码:

    1. class Solution {
    2. public:
    3. vectorint>> fourSum(vector<int>& nums, int target) {
    4. sort(nums.begin(), nums.end());
    5. int size = nums.size();
    6. vectorint>>nnums;
    7. for (int i = 0; i < nums.size();)
    8. {
    9. int cur = i+1;
    10. while (cur < size - 1)
    11. {
    12. int left = cur + 1;
    13. int right = size - 1;
    14. long long a = (long long)target-nums[i] - nums[cur];//找到两数之和为a的两个值
    15. while (left < right)
    16. {
    17. if (nums[left] + nums[right] == a)
    18. {
    19. nnums.push_back({ nums[i],nums[cur],nums[left],nums[right] });
    20. while (right > 1 && nums[right] == nums[right - 1])
    21. right--;
    22. right--;
    23. }
    24. else if (nums[left] + nums[right] > a)
    25. {
    26. while (right > 1 && nums[right] == nums[right - 1])
    27. right--;
    28. right--;
    29. }
    30. else if (nums[left] + nums[right] < a)
    31. {
    32. while (left < size - 1 && nums[left] == nums[left + 1])
    33. left++;
    34. left++;
    35. }
    36. }
    37. while (cur < size - 1 && nums[cur] == nums[cur + 1])
    38. cur++;
    39. cur++;
    40. }
    41. while (i < size - 1 && nums[i] == nums[i + 1])
    42. i++;
    43. i++;
    44. }
    45. return nnums;
    46. }
    47. };

     

  • 相关阅读:
    【文生图】Stable Diffusion XL 1.0模型Full Fine-tuning指南(U-Net全参微调)
    .net 杂谈之二
    理解字符串常量池(JVM)
    C++ 设计模式 —— 组合模式
    MySQL监控innodb的阻塞
    Docker核心原理与实操
    区间查找题解(优先队列+二分)
    shellcode 中 null byte 的成因和避免方式总结
    Java面向对象(史上最详细的整合)
    【JavaScript】String对象知识全解
  • 原文地址:https://blog.csdn.net/m0_69061857/article/details/132816282