问题:
给定一个TargetNumber和一个Array,在Array中找出n个数,这n个数之和等于TargetNumber。
分析:
当n==1时,此时变成了典型的一维数组查找问题,可以采用排序和二分查找的方法。
当n==2时,先按升序排序,ptr1指向数组头,ptr2指向数组尾。若指针所指2数之和大于TargetNumber时,ptr2向队首移动一位,若指针所指的2数之和小于 TargetNumber时,ptr1向队尾移动一位。当2数之和与TargetNumber相等时,2个指针所指的数即为结果。
当n==3时,首先对数组进行排序,定义三个位置ptr1、ptr2、ptr3指向三个位置。初始化ptr1指向队首,并固定ptr1的位置,对ptr2和ptr3使用类似TwoSum的 策略进行搜索,为了提升搜索运行效率,可以在搜索前通过边界判断,缩小搜索范围。ptr2和ptr3相遇后,向后移动ptr1,重新给ptr2和ptr3赋值,再次执 行TwoSum的搜索策略。
代码:ThreeSum
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 5 using namespace std; 6 7 vector<vector<int>> findThreeSum(vector<int> nums, int target) 8 { 9 vector<vector<int>> ret; 10 int n = nums.size(); 11 if(n < 3) 12 return ret; 13 14 sort(nums.begin(), nums.end()); 15 16 for(int ptr1 = 0; ptr1 < n - 2; ptr1++) 17 { 18 int ptr2 = ptr1 + 1; 19 int ptr3 = n - 1; 20 if(nums[ptr1] + nums[ptr1 + 1] + nums[ptr1 + 2] > target) 21 break; 22 if(nums[ptr1] + nums[n - 1] + nums[n - 2] < target) 23 continue; 24 25 while(ptr2 < ptr3) 26 { 27 int sum = nums[ptr1] + nums[ptr2] + nums[ptr3]; 28 if(sum == target) 29 { 30 vector<int> tmp = {nums[ptr1], nums[ptr2], nums[ptr3]}; 31 ret.push_back(tmp); 32 ptr2++; 33 ptr3--; 34 } 35 else if(sum < target) 36 ptr2++; 37 else 38 ptr3--; 39 } 40 } 41 42 return ret; 43 } 44 45 int main() 46 { 47 vector<int> num = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 48 49 vector<vector<int>> ret = findThreeSum(num, 20); 50 51 for(auto x : ret) 52 { 53 std::cout << "items : "; 54 for(auto y : x) 55 { 56 std::cout << y << " "; 57 } 58 std::cout << std::endl; 59 } 60 61 return 0; 62 }
运行结果:
n sum需要用回溯加剪枝的方式。