下定决心终于开始了leetcode之旅,先给自己打打气。
下面是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
刚刚开始看到题的时候,发现这题也太简单了点,直接双重循环不就可以了,面试的时候哪个公司会出这样的题呢。。。。。。事实证明我还是too young too naive。。。。time limit exceeded, O(n2) 是不能忍受的
然后自己又读了一遍题,并没有发现有什么不同,并且我在想如果输入的序列是有顺序的可能还会有什么算法,但是题目中并没有给出。看起来就是只有循环到底这一种方法。。。。哎,大学上到这个程度,真的是很伤自尊的。
无奈,看了一下讨论,发现了一个词hashtable,what?我可是从来没有遇到过这种东西啊,它能干啥?看了几遍还是没有搞懂,压根以前就没有听说过这种东西。。。
后来看到了另外一种算法,就是先排序,然后再进行验证,首先用一种效率比较高的算法,将无序数组排序,然后验证时需要定义前后两个指针,两个相加,如果大于integer,那么右边的指针向左移,如果小于integer,则左边的指针右移,这样的算法时间可以达到
O(nlog(n))
,既然已经有提交成功了的,那么我也就姑且试试吧。
260ms accepted
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
#include <stdio.h>
#include <stdlib.h>
void quickSort(int *nums, int left, int right){
if (left >= right)
return ;
int tmp = nums[left];
int index = left;
int low = left;
int high = right;
while (left < right){
while (left < right && nums[right] > tmp){
right--;
}
nums[index] = nums[right];
index = right;
while (left < right && nums[left] <= tmp){
left++;
}
nums[index] = nums[left];
index = left;
}
nums[index] = tmp;
quickSort(nums, low, left-1);
quickSort(nums, left+1, high);
}
int* twoSum(int* nums, int numsSize, int target) {
int* index = (int *)malloc(2 * sizeof(int));
int* snums = (int *)malloc(numsSize * sizeof(int));
for (int m = 0; m < numsSize; m++){
snums[m] = nums[m];
}
quickSort(nums, 0, numsSize-1);
int i = 0; int j = numsSize - 1;
for (i = 0, j = numsSize -1 ; i != j; ){
if (nums[i] + nums[j] > target)
j--;
else if (nums[i] + nums[j] < target)
i++;
else
break;
}
int flag = -1;
for (int k = 0; k < numsSize; k++){
if (snums[k] == nums[i] && flag != 1){
index[0] = k;
flag = 1;
continue;
}
if (snums[k] == nums[j] && flag != 0){
index[1] = k;
flag = 0;
}
}
int tmp;
index[0]++;
index[1]++;
if (index[0] > index[1]){
tmp = index[0];
index[0] = index[1];
index[1] = tmp;
}
return index;
}
C语言的效率应该要比这个更高,但是目前用排序再验证的方法应该就是这个级别了。
完成了accepted,心里也就有底了,然后下一步就是开始钻研hashtable是个什么东东,看了几个c++的代码后,我才慢慢地懂了,原来是一种能够达到 O(1) 的搜索方法,如果在hashtable中搜索一个东西,只要知道索引的值那么搜索的时间效率非常高,基本上是直接定位,之前建立索引表的方法的效率则是 O(n) ,看到大家都是java,c++的hashtable做的,考虑到python是一门高级语言,我觉得用字典的话,应该实现的效率会非常高,果不其然68ms,accepted
class Solution:
# @param {integer[]} nums
# @param {integer} target
# @return {integer[]}
def twoSum(self, nums, target):
i = 0
dnums = {}
while i < len(nums):
dnums[nums[i]] = i
i = i + 1
i = 0
result = []
while i < len(nums):
if dnums.get(target-nums[i]) and dnums.get(target-nums[i]) != i:
if dnums.get(target-nums[i]) > i:
result.append(i+1)
result.append(dnums.get(target-nums[i])+1)
break
else:
result.append(i+1)
result.append(dnums.get(target-nums[i])+1)
break
i = i + 1
return result