• 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),所以取排序时间复杂度

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

  • 相关阅读:
    mysql DATE_FORMAT FROM_UNIXTIME 的区别
    thinkphp按日期(天)统计数据
    ThinkPHP5 (mySQL) 统计各个时间段内的订单量
    转:mysql按时间统计数据,没有数据的时候自动补充0
    SQL的各种连接Join详解
    查询近7天,近1个月,近3个月每天的数据量,查询近一年每个月的数据量
    MySQL 如何生成日期表
    MySQL 生成日期表
    linux达人养成计划学习笔记(一)——命令基本格式及文件处理命令
    rviz学习笔记(二)——Markers: Points and Lines (C++) 点和线
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14295623.html
Copyright © 2020-2023  润新知