【LeetCode & 剑指offer刷题】数组题1:Two Sum(系列)

 

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

 

1. Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
 
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
  作为LeetCode的首题,Two Sum的名气不小啊,正所谓平生不会TwoSum,刷尽LeetCode也枉然。记得原来在背单词的时候,总是记得第一个单词是abandon,结果有些人背来背去还在abandon,有时候想想刷题其实跟背GRE红宝书没啥太大的区别,都是一个熟练功夫,并不需要有多高的天赋,只要下足功夫,都能达到一个很不错的水平,套用一句鸡汤问来激励下吧,“有些时候我们的努力程度根本达不到需要拼天赋的地步” (来源于博客
//问题:数组找两个和为目标值的数
//方法一:双重遍历(类似选择排序法中的方法),扫描到所有可能的组合
//O(n^2) O(1) 很慢186ms
/*
class Solution
{
public:
    vector<int> twoSum(vector<int>& a, int target)
    {
        for(int i = 0; i < a.size()-1; i++)
        {
            for(int j = i+1; j<a.size(); j++)
            {
                if(a[i]+a[j] == target) return vector<int>{i,j};
            }
        }
        return vector<int>{-1,-1}; //表示没有找到
    }
};*/
/*
方法二:一次遍历+hash表
过程:将值+索引存储在hash表中,每次查找hash表中是否存在某个key(target-a[i],用成员函数find查找即可,每次查找花费常数时间)与当前值和为target
O(n), O(n) 14ms
*/
#include <unordered_map>
class Solution
{
public:
    vector<int> twoSum(vector<int>& a, int target)
    {
        unordered_map <int, int> table
        vector<int> result;
       
        for(int i = 0; i<a.size(); i++) //遍历数组
        {
            //先找再存,这样有先后关系,在已经存的元素中去找可以凑成2sum对的元素,防止同一个数被使用两次
            int numberToFind = target - a[i]; //算出要找的值,
            if(table.find(numberToFind) != table.end()) //如果找得到(当找不到的时候,find函数会返回容器的末尾迭代器)
            {
                result.push_back(table[numberToFind]); //push索引,因为要返回索引
                result.push_back(i);
            }
            else //如果找不到时,存入hash表
                table[a[i]] = i;  //值+索引(key-value)存于hash表中,相同的元素会覆盖前面的索引
            //哈希表无需手动重建空间,当调用[]符号时会自动创建空间,并赋初始值0(如果不手动赋值的话)
        }
        return result;
    }
};
 
167. Two Sum II - Input array is sorted(《剑指offer》第57题)
Given an array of integers that is already sorted in ascending order, 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.
Note:
  • Your returned answers (both index1 and index2) are not zero-based.
  • You may assume that each input would have exactly one solution and you may not use the same element twice.
Example:
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
 
/*
问题:所给数组为有序数组(递增),找和为特定值的两个数
方法:双指针法
过程:前后各一指针,当和小于target时,往中间移动左边指针,当和大于target时,往中间移动右边指针直到相遇或者等于target
O(n), O(1) (由于利用了数组有序性的特点,优于哈希表的方法)
*/
class Solution
{
public:
    vector<int> twoSum(vector<int>& a, int target)
    {
        vector<int> result;
        if(a.empty()) return result;
       
        int left = 0, right = a.size()-1;
        while(left < right)
        {
            if(a[left] + a[right] < target) left++;
            else if(a[left] + a[right] > target) right--;
            else
            {
                result.push_back(left+1); //题目要求索引以1开始
                result.push_back(right+1);
                return result;
            }
        }
       
        return result;
    }
};
 
653. Two Sum IV - Input is a BST
Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.
Example 1:
Input:
5
/ \
3 6
/ \ \
2 4 7
 
Target = 9
 
Output: True
Example 2:
Input:
5
/ \
3 6
/ \ \
2 4 7
 
Target = 28
 
Output: False
 
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
/*
问题:在BST中找two sum的两个数,判断是否存在
方法:中序遍历后查找即可
O(n) O(n)(因为每个结点都会被访问一次,故会有n次递归,递归栈的空间复杂度为o(n))
*/
class Solution
{
public:
    bool findTarget(TreeNode* root, int k)
    {
        vector<int> a; //用于存结点值
       
        inorder(root, a);
        int left = 0, right = a.size()-1;
        while(left<right)
        {
            int sum = a[left] + a[right];
            if(sum < k) left++;
            else if(sum > k) right--;
            else return true;
        }
        return false;
    }
private:
    void inorder(TreeNode* root, vector<int>& a)
    {
        if(root == nullptr) return;
       
        inorder(root->left, a);
        a.push_back(root->val);
        inorder(root->right, a);
    }
};
 
 
 
 
 

 

posted @ 2019-01-05 13:34  wikiwen  阅读(463)  评论(0编辑  收藏  举报