• 【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 };
  • 相关阅读:
    hadoop学习摘要
    尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。
    sqlserver 2012 IDE中 Windows身份验证连接服务器报错 ,Login failed for user 'xxxAdministrator'. 原因: 找不到与提供的名称匹配的登录名。
    不重复随机数列生成算法
    异步和等待(async和await)
    mvc和mvvm的区别?
    Redis命令大全
    Java NIO 三大组件之 Buffer
    Java NIO 三大组件之 Channel
    Java NIO概述
  • 原文地址:https://www.cnblogs.com/huxiao-tee/p/4232569.html
Copyright © 2020-2023  润新知