[LeetCode] Two Sum
https://leetcode.com/problems/two-sum/
Given an array of integers, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. You may assume that each input would have exactly one solution. Input: numbers={2, 7, 11, 15}, target=9 Output: index1=1, index2=2
这道题肯定要对于每一个元素,查找输入数组中有没有和它相加之后等于 target 的数字,伪代码如下:
foreach ($input as $key => $value) { if (in_array($target - $value, $input)) //... }
对于输入数组的每一个元素 val,都要查找 target - val 是 O(N^2) 的复杂度,一开始我的思路是用哈希表存放每个元素和其下标的对应关系(记录每个数对应的前两次出现的下标),类似于这种思路:
class tuple { public: int first; int second; } unordered_map<int, tuple> m;
因为纯 C 并没有自带哈希表的数据结构,所以采用的静态数组,提交之后发现输入数据里还有负值,这个可以通过多分配一些空间来解决,但是再这样下去此题已经失去意义了。
后来想到先将输入数据排序,然后用 left 和 right 分别指向排序后数组的两端,求和 sum = inputs[left] + inputs[right],如果 sum < target,则 left 右移,反之 right 左移,直到 sum == target。
typedef struct { int index_; int value_; } input_element; int compare(const void * a, const void * b) { return ((input_element*)a)->value_ - ((input_element*)b)->value_; } void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } int* twoSum(int* nums, int numsSize, int target) { int *ret = (int*)malloc(2 * sizeof(int)); input_element * inputs = (input_element *)malloc(numsSize * sizeof(input_element)); for (int i = 0; i < numsSize; ++i) { inputs[i].index_ = i + 1; inputs[i].value_ = nums[i]; } qsort(inputs, numsSize, sizeof(input_element), compare); int left = 0; int right = numsSize - 1; do { int sum = inputs[left].value_ + inputs[right].value_; if (sum < target) { ++left; } else if (sum > target) { --right; } else { break; } } while (1); //题目已经指出这个解肯定存在 ret[0] = inputs[left].index_; ret[1] = inputs[right].index_; if (ret[0] > ret[1]) { swap(ret, ret + 1); } return ret; }
16 / 16 test cases passed.
Status: Accepted
Runtime: 4 ms