• 15. 三数之和


    题目

    这道题看似和两数之和的的哈希法,但用哈希比较麻烦

    分析

    双指针

     1 class Solution {
     2 public:
     3     
     4     vector<vector<int>> threeSum(vector<int>& nums) {
     5         vector<vector<int>>res;
     6         sort(nums.begin(),nums.end());
     7         for(int i = 0;i < nums.size();i++){
     8             if(nums[i] > 0 ) return res;
     9             if(i > 0 && nums[i] == nums[i-1]) continue;
    10             int left = i+1,right = nums.size()-1;
    11             while(left < right){
    12                 if(nums[i] + nums[left] + nums[right] > 0) right--;
    13                 else if(nums[i] + nums[left] + nums[right] < 0) left++;
    14                 else{
    15                     res.push_back(vector<int>{nums[i],nums[left],nums[right]});
    16                     while(left < right && nums[right] == nums[right-1]) right--;
    17                     while(left < right && nums[left] == nums[left+1]) left++;
    18                     left++;
    19                     right--;
    20                 }
    21             }
    22 
    23         }
    24 
    25         return res;
    26         
    27     }
    28 };

    时间复杂度O(N2) ,空间复杂度O(logN)。我们忽略存储答案的空间,额外的排序的空间复杂度为 O(logN)。我们修改了输入的数组 extit{nums}nums,在实际情况下不一定允许,因此也可以看成使用了一个额外的数组存储了 nums 的副本并进行排序,空间复杂度为 O(logN)

    注意:

    1. 第九行的去重逻辑应该是如果该元素和上一个元素相同,那么就不考虑这个元素。去重逻辑不应该是下一个元素和当前相同,如果

    这样考虑将会导致忽略开头元素相同的情况,如-1,-1,2

    2. 第十六十七行的去重逻辑应该再找到一个三元组后,而不应该放在之前

    3. 双指针之前一般要排序。

    4. 三数之和可以用双指针,那么LeetCode1.两数之和可不可以用双指针呢 ?怎么改就能用了呢?

        因为两数之和那个题是要返回索引和数值所以不能用双指针,用map哈希。若按照本题将两数之和改成返回数组元素,则可以用双指

    针,代码如下。

     1   vector<vector<int>> tSum(vector<int>& nums, int target) {
     2         vector<vector<int>> res;
     3         sort(nums.begin(),nums.end());
     4         int left = 0,right = nums.size()-1;
     5         while(left < right){
     6             if(nums[left] > targrt || nums[right] < target ) return res;
     7             if(nums[left] + nums[right] < target){left++;}
     8             else if(nums[left] + nums[right] > target) {right--;}
     9             else { 
    10                 res.push_back(vector<int>{nums[left],nums[right]});
    11                 while(left < right && nums[right] == nums[right-1]) right--;
    12                 while(left < right && nums[left] == nums[left+1]) left++;
    13                 right--;
    14                 left++;
    15             }
    16         }        
    17         return res;
    18     }

    这里几乎思路一样,只用外部一个循环就可以。

    时间复杂度为O(nlogn),因为找两数的循环的时间复杂度为O(n),C++stl中的排序为改进后的快速排序时间复杂度为O(nlogn),所以取排序时间复杂度

    这样可以看出在求解两数之和问题时,一般用哈希,因为若用双指针时间复杂度变高了。

  • 相关阅读:
    Android中,粗暴的方式,修改字体
    Android 修改字体,跳不过的 Typeface
    Android 字体修改,所有的细节都在这里 | 开篇
    当你在设置里修改字体大小的时候,到底在修改什么
    使用 Palette 让你的 UI 色彩与内容更贴合
    View.post() 不靠谱的地方你知道吗?
    九月了,回头看看八月你错过的原创好文
    海外 App 的推送服务,试试 FCM 吧!!!
    微信原图泄露的只能是 Exif ,你的隐私不在这!!!
    RecyclerView 配合 DiffUtil,好用到飞起
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14295623.html
Copyright © 2020-2023  润新知