算法练习-寻找和为定值的两个数
练习问题来源
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].
解法
- 先对 数组
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);
}
}