一個非常簡單的算法題是否願意挑戰一下呢


 求兩個數之和。這個問題夠簡單吧!能做對絕對不是問題,問題是你是否能做的比較好。好了,請看題目:
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.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
看了題目之后,心中是否已經有了答案。很簡單蠻力法嘛,一個雙循環就可以搞定了。但是有沒有更好一點的方法呢?
如果你已經想到了也沒必要往下看了。
如果你還沒有什么頭緒,那么稍微往HashTable想想,估計你們也想到了。其實也是很簡單,只是有時候想問題的方向不對,就老是想不到點子上罷了。如果還沒想到的話,就往下看一下吧!
相比較於,用一個雙循環,在時間效率上面可能不是很好。那么久可以很容易想到,也經常聽到的“空間換時間”,就是這樣,我們可以使用一個字典鍵值對保存中間值,減少一次循環,變成單循環,那么時間效率就可以得以提升。
那么這個字典到底保存什么呢?保存目標值減去當前數組的整數值(鍵)和數組整數值的下標(值)。當我們執行循環時,每循環到一個數組中的整數,我們就判斷這個整數是否是字典中的鍵,如果不是我們就按照前面說的鍵值存入字典中,題目說了有且只有一對數字是符合條件的,那么也就不用考慮重復鍵了。如果是,我們就找到了這兩個整數,接着就是返回整兩個整數的下標了。第一個整數的下標就是當前字典的鍵對應的值,第二個整數的下標就是當前循環到的i值。就是這么簡單!如果我說的不夠清楚就直接看代碼。
以下是C#的實現:
 1  using System;
2 using System.Collections.Generic;
3
4 namespace XiaoLiang
5 {
6 public class TwoSum
7 {
8 public int[] TwoSum(int[] nums, int target)
9 {
10 int[] result = new int[2];
11 Dictionary<int, int> dictionary = new Dictionary<int, int>();
12 for (int i = 0; i < nums.Length; i ++ )
13   {
14 if(dictionary.ContainsKey(nums[i]))
15 {
16 result[0] = dictionary[nums[i]];
17 result[1] = i;
18 return result;
19 }
20 else
21 {
22 dictionary.Add(target - nums[i] , i);
23 }
24 }
25 return result;
26 }
27 }
28

 

以下是C++的實現:
 1 class Solution {
2 public:
3 vector<int> twoSum(vector<int>& nums, int target) {
4 int i = 0, n = nums.size();
5 unordered_map<int, int> m;
6 vector<int> ret;
7
8 for (i = 0; i < n; ++i)
9 {
10 if (m.find(target - nums[i]) != m.end())
11 {
12 ret.push_back(m[target - nums[i]]);
13 ret.push_back(i);
14 break;
15 }
16 m[nums[i]] = i;
17 }
18
19 return ret;
20 }
21 };

 

 

如果有什么說的不對的地方歡迎拍磚,有更好的方法可以共享。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com