【LeetCode & 剑指offer刷题】Two Sum(系列)

Evernote Export

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 );
    }
};
 
 
 
 
 

猜你喜欢

转载自www.cnblogs.com/wikiwen/p/10156238.html