zoukankan      html  css  js  c++  java
  • 1. 两数之和(简单)

    题目链接

    问题:

    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

    示例:

    给定 nums = [2, 7, 11, 15], target = 9

    因为 nums[0] + nums[1] = 2 + 7 = 9
    所以返回 [0, 1]

    通过次数1,348,299
    提交次数2,732,584

    思路:

    ①双指针扫描法(O(n)):一个头指针一个尾指针,令头尾指针指的数相加,小了头指针后移,大了尾指针前移(即杨式矩阵的思维方式).
    ***** 杨式矩阵(n*m):行和列都是递增的.
    ***** 查找某值x:从右上角(本行最大,本列最小,或者左下角-本列最大,本行最小)那个数字开始,小了向下走,大了向左走,最多走n+m步,时间复杂度O(n+m).
    ②二分法(O(nlogn)):前提是数据有序. 设置一个头指针p,排序后按序指向某个数x,用二分查找target-x,若找到就返回这两个数的下标,否则p后移继续查找.
    ③哈希表(O(n)):unordered_map基于哈希表不保证数据有序性,map基于红黑树会保证数据有序性,哈希表无论数据有序无序都能用,维护的是当前位置之前的集合.

     1 /* 双指针扫描法 */
     2 #include <vector>
     3 using namespace std;
     4 
     5 class Solution {
     6     public:
     7         typedef pair<int, int> PII;
     8         vector<int> twoSum(vector<int>& nums, int target) {
     9             vector<PII> vec;
    10             for(int i=0; i<nums.size(); i++) {
    11                 vec.push_back(PII(nums[i], i));
    12             }
    13             sort(vec.begin(), vec.end());
    14             int p=0, q=vec.size()-1;
    15             while(1) {
    16                 int a=vec[p].first;
    17                 int b=vec[q].first;
    18                 if(a+b==target) break;
    19                 if(a+b<target) p++;
    20                 else q--; 
    21             }
    22             int a=vec[p].second;
    23             int b=vec[q].second;
    24             if(a>b) swap(a, b);
    25             vector<int> ret;
    26             ret.push_back(a);
    27             ret.push_back(b);
    28             return ret;
    29         }
    30 }; 
     1 /* 二分法 */
     2 #include <vector>
     3 using namespace std;
     4 
     5 class Solution {
     6 public:
     7     typedef pair<int, int> PII;
     8     int my_binary_search(vector<PII> &vec, int L, int x) {
     9         int R=vec.size()-1, mid;
    10         while(L<=R) {
    11             mid=(L+R)>>1;
    12             if(vec[mid].first==x) return vec[mid].second;
    13             if(vec[mid].first<x) L=mid+1;
    14             else R=mid-1;
    15         }
    16         return -1;
    17     }
    18     
    19     vector<int> twoSum(vector<int>& nums, int target) {
    20         vector<PII> vec;
    21         vector<int> ret;
    22         for(int i=0; i<nums.size(); i++) {
    23             vec.push_back(PII(nums[i], i));
    24         }
    25         sort(vec.begin(), vec.end());
    26         for(int i=0; i<vec.size(); i++) {
    27             int id1=vec[i].second;
    28             int id2=my_binary_search(vec, i+1, target-vec[i].first);
    29             if(id2==-1) continue;
    30             if(id1>id2) swap(id1, id2);
    31             ret.push_back(id1);
    32             ret.push_back(id2);
    33             break;
    34         }
    35         return ret;
    36     }
    37 };
     1 /* 哈希表 */
     2 #include <vector>
     3 #include <unordered_map>
     4 using namespace std;
     5 
     6 class Solution {
     7 public:
     8     typedef pair<int, int> PII;
     9     vector<int> twoSum(vector<int>& nums, int target) {
    10         vector<int> ret;
    11         unordered_map<int, int> ha;
    12         for(int i=0; i<nums.size(); i++) {
    13             int val=target-nums[i];
    14             if(ha.find(val)==ha.end()) {
    15                 ha[nums[i]]=i;
    16             }else {
    17                 ret.push_back(ha[val]);
    18                 ret.push_back(i);
    19                 break;
    20             }
    21         }
    22         return ret;
    23     }
    24 };

    纪念在力扣刷的第一题——这里要感谢一下船长,虽然我不是船员.

  • 相关阅读:
    10.30 afternoon
    10.29 afternoon
    10.29 morning

    10.27 noip模拟试题
    codevs 3052 多米诺 二分图匹配
    poj 1849 Two
    10.26 noip模拟试题
    10.25 noip模拟试题
    .NET Core EF 版本问题
  • 原文地址:https://www.cnblogs.com/wwqzbl/p/13617864.html
Copyright © 2011-2022 走看看