• LeetCode之“散列表”:Two Sum && 3Sum && 3Sum Closest && 4Sum


      1. Two Sum 

      题目链接

      题目要求:

      Given an array of integers, find two numbers such that they add up to a specific target number.

      The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

      You may assume that each input would have exactly one solution.

      Input: numbers={2, 7, 11, 15}, target=9
      Output: index1=1, index2=2

      这道题如果使用Brute Force,在LeetCode上会超时,具体程序如下:

     1 vector<int> twoSum(vector<int>& nums, int target) {
     2     vector<int> ret;
     3     int sz = nums.size();
     4     for(int i = 0; i < sz; i++)
     5         for(int j = i + 1; j < sz; j++)
     6         {
     7             if(nums[i] + nums[j] == target)
     8             {
     9                 ret.push_back(i);
    10                 ret.push_back(j);
    11                 return ret;
    12             }
    13         }
    14         
    15     return ret;
    16 }
    View Code

      如果我们利用哈希表来实现,则时间复杂度能达到O(n),程序如下:

     1 vector<int> twoSum(vector<int>& nums, int target) {
     2     vector<int> ret;
     3     unordered_map<int, int> hashMap;
     4     int sz = nums.size();
     5     for(int i = 0; i < sz; i++)
     6     {
     7         int tmp = target - nums[i];
     8         if(hashMap.find(tmp) != hashMap.end())
     9         {
    10             ret.push_back(hashMap[tmp] + 1);
    11             ret.push_back(i + 1);
    12             break;
    13         }
    14         else
    15             hashMap[nums[i]] = i;
    16     }
    17         
    18     return ret;
    19 }

       在上述程序中我们使用了unordered_map这个数据结构,它要比map要快,因为它存贮和访问元素是根据元素的哈希值来进行的。在cplusplus.com上有比较了这两者在访问单个元素时的速度:

      unordered_map containers are faster than map containers to access individual elements by their key, although they are generally less efficient for range iteration through a subset of their elements.

      2. 3Sum

      题目链接

      题目要求:

      Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

      Note:

    • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
    • The solution set must not contain duplicate triplets.
        For example, given array S = {-1 0 1 2 -1 -4},
        A solution set is:
        (-1, 0, 1)
        (-1, -1, 2)

      该题解法参考自一博文。要解决该题,首先我们将数组排序,然后将其降维(即降为2维),最后再调用Two Sum算法。具体程序中,我们采用的是Two Pointers方法,具体程序如下:

     1 void twoSum(vector<int>& nums, int start, int target, vector<vector<int> >& ret) {
     2     int head = start, tail = nums.size() - 1;
     3     while(head < tail)
     4     {
     5         int tmp = nums[head] + nums[tail];
     6         if(tmp < target)
     7             head++;
     8         else if(tmp > target)
     9             tail--;
    10         else
    11         {
    12             ret.push_back({nums[start-1], nums[head], nums[tail]});
    13             
    14             // 去除重复
    15             int k = head + 1;
    16             while(k < tail && nums[k] == nums[head])
    17                 k++;
    18             head = k;
    19             
    20             // 去除重复
    21             k = tail - 1;
    22             while(k > head && nums[k] == nums[tail])
    23                 k--;
    24             tail = k;
    25         }
    26     }
    27 }
    28 
    29 vector<vector<int>> threeSum(vector<int>& nums) {
    30     vector<vector<int> > ret;
    31     sort(nums.begin(), nums.end());
    32     
    33     int sz = nums.size();
    34     for(int i = 0; i < sz - 2; i++)
    35     {
    36         // 去除重复
    37         if(i > 0 && nums[i] == nums[i - 1])
    38             continue;
    39         
    40         int target = 0 - nums[i];
    41         twoSum(nums, i + 1, target, ret);
    42     }
    43         
    44     return ret;
    45 }
    View Code

      3. 3Sum Closest

      题目链接

      题目要求:

      Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

        For example, given array S = {-1 2 1 -4}, and target = 1.
        The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

      该题解法跟上题类似:

     1 void threeSumClosest(vector<int>& nums, int start, int target, int& cloSum) {
     2     int head = start, tail = nums.size() - 1;
     3     while (head < tail)
     4     {
     5         int tmp = nums[start - 1] + nums[head] + nums[tail];
     6         if(tmp > target)
     7         {
     8             if(tmp - target < abs(cloSum - target))
     9                 cloSum = tmp;
    10             tail--;
    11         }
    12         else if(tmp < target)
    13         {
    14             if(target - tmp < abs(target - cloSum))
    15                 cloSum = tmp;
    16             head++;
    17         }
    18         else
    19         {
    20             cloSum = target;
    21             return;
    22         }
    23     }
    24 }
    25 
    26 int threeSumClosest(vector<int>& nums, int target) {
    27     int cloSum = INT_MAX - 10000;   // 减去10000,以防溢出
    28     sort(nums.begin(), nums.end()); // 要充分利用已排序这个条件
    29     int sz = nums.size();
    30     for(int i = 0; i < sz - 2; i++)
    31     {
    32         // 去除重复
    33         if(i > 0 && nums[i] == nums[i-1])
    34             continue;
    35             
    36         threeSumClosest(nums, i + 1, target , cloSum);
    37     }
    38     
    39     return cloSum;
    40 }
    View Code

      4. 4Sum

      题目链接

      题目要求:

      Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

      Note:

    • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
    • The solution set must not contain duplicate quadruplets.
        For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
        A solution set is:
        (-1,  0, 0, 1)
        (-2, -1, 1, 2)
        (-2,  0, 0, 2)

      该题解法跟3Sum类似:

     1 void twoSum(vector<int>& nums, int start, int target, int first, int second, vector<vector<int>>& ret)
     2 {
     3     int head = start, tail = nums.size() - 1;
     4     while(head < tail)
     5     {
     6         int tmp = nums[head] + nums[tail];
     7         if(tmp < target)
     8             head++;
     9         else if(tmp > target)
    10             tail--;
    11         else
    12         {
    13             ret.push_back({first, second, nums[head], nums[tail]});
    14             
    15             // 去除重复
    16             int k = head + 1;
    17             while(k < tail && nums[k] == nums[head])
    18                 k++;
    19             head = k;
    20             
    21             // 去除重复
    22             k = tail - 1;
    23             while(k > head && nums[k] == nums[tail])
    24                 k--;
    25             tail = k;
    26         }
    27     }
    28 }
    29 
    30 vector<vector<int>> fourSum(vector<int>& nums, int target) {
    31     vector<vector<int>> ret;
    32     sort(nums.begin(), nums.end());
    33     int sz = nums.size();
    34     for(int i = 0; i < sz - 3; i++)
    35     {
    36         // 去除重复
    37         if(i > 0 && nums[i] == nums[i-1])
    38             continue;
    39         for(int j = i + 1; j < sz - 2; j++)
    40         {
    41             // 去除重复
    42             if(j > i + 1 && nums[j] == nums[j-1])
    43                 continue;
    44             twoSum(nums, j + 1, target - nums[i] - nums[j], nums[i], nums[j], ret);
    45         }
    46     }
    47         
    48     return ret;
    49 }
    View Code
  • 相关阅读:
    MyEclipse数据库反向生成实体类
    Struts2部分标签
    如何使用 Jmeter 发送 Json 请求
    [转]Perfmon
    Jmeter 施压 SQL server数据库的时候,如何设置?
    Tomcat 安装之后,双击Tomcat.exe,无法运行成功,怎么办?
    Jmeter 在什么情况下定义多个thread group?
    Watir RAutomation VS AutoIt to deal with popup
    RAutomation 在 Watir中的使用
    AutoIt:如何处理应用程序端口被占用的情况
  • 原文地址:https://www.cnblogs.com/xiehongfeng100/p/4590472.html
Copyright © 2020-2023  润新知