算法练习-寻找和为定值的两个数

练习问题来源

https://leetcode.com/problems/two-sum/
https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/02.02.html

要求

输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
** 例如: **

Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

解法

  1. 先对 数组 nums 快速排序,排序过程中通过 indexnums 记住原数列的初始序列;
    初始数列:
nums = [7](150, 24, 79, 50, 88, 345, 3);
indexnums = [7](0, 1, 2, 3, 4, 5, 6)

** 排序后:**

nums = [7](3, 24, 50, 79, 88, 150, 345)
indexnums = [7](6, 1, 3, 2, 4, 0, 5)

该步骤时间复杂度为 $ nO(\log n) $
2. 对排好序的 nums 两端开始,判断 nums[iL] + nums[iR]target 的大小

if ( nums[iL] + nums[iR] < target)    iL++;
if ( nums[iL] + nums[iR] > target)    iR--;
// 直到  nums[iL] + nums[iR] == target

代码实现

vector<int> twoSum(vector<int>& nums, int target) {
    // sort(nums.begin(), nums.end());
    vector<int> index, pos;
    for(int k = 0; k < nums.size(); ++k){
        index.push_back(k);
    }

    int i = 0, j = nums.size() - 1;
    QuickSort(nums, index, 0, j);
    while(i < j){
        if(nums[i] + nums[j] < target){
            ++i;
        }
        if(nums[i] + nums[j] > target){
            --j;
        }
        if(nums[i] + nums[j] == target){
            if(index[i] < index[j]){
                pos.push_back(index[i]);
                pos.push_back(index[j]);
            }
            else{
                pos.push_back(index[j]);
                pos.push_back(index[i]);
            }
            return pos;
        }
    }
    cout << "There is no solution" << endl;
    return pos;
}

void QuickSort(vector<int>& nums, vector<int>& indexnums, int iL, int iR){
    int i, j, numTemp, indexTmep;
    if(iL < iR){
        i = iL; j = iR;
        numTemp = nums[i];
        indexTmep = indexnums[i];
        while(i < j){
            while(i < j && nums[j] > numTemp){  // right -> left, find a number less than numTemp
                --j;
            }
            if(i < j){
                nums[i] = nums[j];
                //Swap(indexnums, i, j);
                indexnums[i] = indexnums[j];
                ++i;
            }

            while(i < j && nums[i] < numTemp){ // left -> right, find a number greater than numTemp
                ++i;
            }
            if(i < j){
                nums[j] = nums[i];
                //Swap(indexnums, i, j);
                indexnums[j] = indexnums[i];
                --j;
            }
        }

        nums[i] = numTemp;
        indexnums[i] = indexTmep;
        QuickSort(nums, indexnums, iL, i-1);
        QuickSort(nums, indexnums, i+1, iR);
    }
}
posted @ 2016-06-02 11:48  NobodyZhou  阅读(145)  评论(0编辑  收藏  举报