演算法-兩數之和

zeng沐白發表於2018-07-07

題目

給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。

你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。

示例:
給定 nums = [2, 7, 11, 15], target = 9
因為 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
複製程式碼
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 //程式導向的解法;這是最直接的思路。
int* twoSum(int* nums, int numsSize, int target) {
    int *a=(int *)malloc(2*sizeof(int));
    //外層index從0開始遍歷
    int index = 0;
    while (index < numsSize - 1) {
    //內層從外層當前下標index的下一個元素開始遍歷即i= index + 1
        int i = index + 1;
        while (i < numsSize) {
        //判斷兩個元素之和是否等於target,如果相等,儲存值並返回。
            if (*(nums + i) + *(nums + index) == target) {
                *(a + 0)= index;
                *(a + 1) = i;
                return a;
            }
            i ++;
        }
        index ++;
    }
    return a;
}
複製程式碼
//思路升級
//c++ 雜湊map  空間換時間
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> valueMap;
        for (int i = 0 ; i < nums.size(); i++) {
            int searchValue = target - nums[i];
            map<int,int>::iterator it ;
            //通過value查詢是否存在,該操作時間複雜度為O(1);
            it = valueMap.find(searchValue);
            if (it != valueMap.end()) {
                vector<int> collect;
                collect.push_back(valueMap[searchValue]);
                collect.push_back(i);
                return collect;
            }
            valueMap.insert(pair<int, int>(nums[i],i));
        }
        vector<int> collect;
        return collect; 
    }
};
複製程式碼

小結:

  1. 該題難度不大,直接使用程式導向的方法就能求解。
  2. 該問題步驟分解中,因為已知和以及其中一個加數求另外一個加數,轉換到程式中就是一個查詢的問題->一個已知集合查詢特定值得問題.

一個已知集合查詢特定值得問題,會直接導致兩種思路:

  1. 遍歷查詢->優化遍歷方法
  2. 空間換時間->雜湊查詢(這裡會產生一種資料結構,它會把一個數值和數值的索引儲存【起到儲存的作用】,並能快速通過索引查詢到對應的數值。另外由於不存在相同索引,所以可以【儲存同一索引最後狀態的值】,這個性質可以對某類問題做優化,例如最長不重複字元子串問題,通過值替換能儲存相同字元的最後位置j(當前位置),假設被替換前的值為i ,那麼當前子串長度len = j - i )。

思維路線: ->常規思路是否可解; ->是否存查詢問題->是否可以使用空間換時間(雜湊查詢,備忘錄等)

待完善....

相關文章