題目
給定一個整數(shù)數(shù)組和一個目標值,找出數(shù)組中和為目標值的兩個數(shù)。
你可以假設(shè)每個輸入只對應(yīng)一種答案,且同樣的元素不能被重復(fù)利用。
示例:給定 nums = [2, 7, 11, 15], target = 9因為 nums[0] + nums[1] = 2 + 7 = 所以返回 [0, 1]
暴力法
簡單來說只要遍歷每個元素x,并查找是否存在一個值和
target-x相等就可以了。但是缺點也是很明顯的,它的時間復(fù)雜度達到了O(n2),這顯然不
是我們要的。
C語言版
twoSum(int* nums, int numsSize, int target)
{
for(int i = 0;i < numsSize;i++){
for (int j = i+1;j < numsSize;j++){
if ((nums[i]+nums[j]) == target) {
int *result = (int *)malloc(sizeof(int) * 2);
result[0] = nums[i];
result[1] = nums[j];
return result;
}
}
}
return NULL;
}
Go語言版
func twoSum(nums []int, target int) []int {
l := len(nums)
result := make([]int, 2, 2)
for i := 0; i < l; i++ {
for j := i + 1; j < l; j++ {
if (nums[i] + nums[j]) == target {
result[0] = i
result[1] = j
return result
}
}
}
return result
}
Hash法
實際上,當我們遍歷數(shù)組去查找和target-x相等的數(shù)時候,每一次都要從頭開始遍歷。而其實
在x前面的數(shù)其實已經(jīng)被訪問過多次了,這種行為確實是比較浪費時間的。而這時候我們需要一個
表來記錄已經(jīng)訪問過的數(shù)據(jù),并且訪問這個表中的數(shù)據(jù)的時間復(fù)雜度越低越好,而Hash表顯然符合
這個性質(zhì),并且其訪問數(shù)據(jù)在理論在可以達到O(1)。
C語言版
typedef struct node{
int key;
int value;
struct node *next;
}node_t;
typedef struct hash_table {
int capacity;
node_t **hashtab;
}hash_table_t;
hash_table_t *hash_table_create(int capacity)
{
hash_table_t *hash_table = (hash_table_t *)malloc(sizeof(hash_table_t));
hash_table->hashtab = (node_t **)malloc(sizeof(node_t*) * capacity);
for(int i = 0;i < capacity;i++)
hash_table->hashtab[i] = NULL;
hash_table->capacity = capacity;
return hash_table;
}
int get_hash_key(int n, int capacity){
return abs((65535 * n + 1048575)) % capacity;
}
int hash_table_value(hash_table_t *hash_table,int key)
{
int index = get_hash_key(key,hash_table->capacity);
node_t *curr = hash_table->hashtab[index];
while(curr != NULL){
if(curr->key == key)
return curr->value;
curr = curr->next;
}
return -1;
}
void hash_table_add(hash_table_t *hash_table,int key,int value)
{
int index = get_hash_key(key,hash_table->capacity);//get hash key
node_t *node = (node_t*)malloc(sizeof(node_t));
node->next = NULL;
node->next = hash_table->hashtab[index];
node->key = key;
node->value = value;
hash_table->hashtab[index] = node;
}
void hash_table_free(hash_table_t* hash_table)
{
for(int i=0;i<hash_table->capacity;i++){
node_t* curr = hash_table->hashtab[i];
while(curr!=NULL){
node_t* hold = curr;
curr->next = curr;
free(hold);
}
}
free(hash_table->hashtab);
free(hash_table);
}
int* twoSum(int* nums, int numsSize, int target)
{
hash_table_t* hash_table = hash_table_create(numsSize/2);
for(int index=0;index<numsSize;index++){
int idx = hash_table_value(hash_table, target - nums[index]);
if(idx>=0){
int* result = (int*)malloc(sizeof(int)*2);
result[1] = index;
result[0] = idx;
return result;
}
hash_table_add(hash_table, nums[index], index);
}
return NULL;
}
Go語言版
//Hash
func twoSum(nums []int, target int) []int {
l := len(nums)
result := make([]int, 2, 2)
tmp := make(map[int]int)
for i := 0; i < l; i++ {
if j, ok := tmp[target-nums[i]]; ok {
result[0] = j
result[1] = i
return result
} else {
tmp[nums[i]] = i
}
}
return result
}