zoukankan      html  css  js  c++  java
  • 【Leetcode】【Medium】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

    本题特点:

    1、无序数组;

    2、结果唯一;

    解题1:o(nlogn)

    1、对数组进行排序;o(nlogn)

    2、在有序数组中寻找和等于target的两个数a,b;o(n)

    解题步骤:

    1、新建数组副本,并对副本排序;

    2、从有序副本的两端开始查找,找到和等于target的两个数,记录其下标为i和j;

    3、两遍遍历原数组,第一遍寻找a[i]的原始位置index1,第二遍寻找a[j]的原始位置index2;(比一遍遍历具有更少的比较次数)

    4、按照从小到大的顺序生成返回数组,返回index1和index2;

    注意:

    1、原数组中可能包含重复的元素;

    2、不能使用原数组排序,本题需要记录原数组元素顺序。即使不需要原始顺序,如无特殊要求,也不应该在函数内对原数组进行操作;

    3、同时,此题在细节的时间复杂度要求非常苛刻(亲测):

      ①、即使相同时间复杂度的排序算法,也有很大区别,此题排序时必须使用最优秀的nlogn算法,即STL源码中使用的优化改进后的快速排序算法;我使用了标准堆排序算法,未能通过;

      ②、对数组元素进行比较和交换操作,不如先对整数进行比较和交换,然后再赋值给数组;

      ③、减少所有不必要的赋值、比较和交换操作;

    代码:

     1 class Solution {
     2 public:
     3     vector<int> twoSum(vector<int> &numbers, int target) {
     4         int length = numbers.size();
     5         vector<int> numbers_copy = numbers;
     6         sort(numbers_copy.begin(), numbers_copy.end());
     7         
     8         int i = 0;
     9         int j = length - 1;
    10         while (i < j) {
    11             if (numbers_copy[i] + numbers_copy[j] < target)
    12                 i++;
    13             else if (numbers_copy[i] + numbers_copy[j] > target)
    14                 j--;
    15             else
    16                 break;
    17         }
    18         
    19         int index1 = 0;
    20         int index2 = length - 1;
    21         while(index1 < length && numbers_copy[i] != numbers[index1])
    22             index1++;
    23         while(index2 > 0 && numbers_copy[j] != numbers[index2])
    24             index2--;
    25         if (index1 > index2)
    26             swap(index1, index2);
    27 
    28         vector<int> result {index1 + 1, index2 + 1};
    29         return result;
    30     }
    31 };

    解题2:

    使用哈希表,使查找的复杂度为o(1),达到o(n)时间复杂度;

    解题步骤:

    1、新建一个两元素数组作为返回数组,再新建一个hash表结构;

    2、遍历原始数组,遇到的每一个元素i:

      如果hash表中已存在target - a[i],则a[i]和target - a[i]就是要找的两个数,且target-a[i]先出现;

      如果hash表中不存在,则将键a[i]传入hash表,值设置为其下标值i;(注意此时hash表中可能已经存在a[i])

    代码:

     1 class Solution {
     2 public:
     3     vector<int> twoSum(vector<int> &numbers, int target) {
     4         vector<int> result(2);
     5         unordered_map<int, int> hmap;
     6         int length = numbers.size();
     7         for (int i = 0; i < length; ++i) {
     8             if (hmap.find(target - numbers[i]) != hmap.end()) {
     9                 result[0] = hmap[target - numbers[i]] + 1;
    10                 result[1] = i + 1;
    11                 return result;
    12             } else {
    13                 hmap[numbers[i]] = i;
    14             }
    15         }
    16         return result;
    17     }
    18 };
  • 相关阅读:
    【基础】jquery全选、反选、全不选代码
    【基础】jquery全选、反选、全不选代码
    收集一些程序员励志经典名言
    收集一些程序员励志经典名言
    收集一些程序员励志经典名言
    防止表单重复提交的解决方案整理
    Git使用教程
    2019牛客暑期多校训练营(第二场)J Subarray
    Hibernate-配置
    与项目欧拉速度比较:C vs Python与Erlang vs Haskell
  • 原文地址:https://www.cnblogs.com/huxiao-tee/p/4232569.html
Copyright © 2011-2022 走看看