leetcode之问题一:Two Sum

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34302921/article/details/85379660

1. 问题描述

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same elements twice.

Example: Given nums = [2, 7, 11, 15], target = 9. Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

2. 算法思想

A. 暴力破解:对于nums中的每一个元素a,根据和求出另一个元素的值b,从nums中寻找b,若找到则退出。核心代码采用了2个for循环,时间复杂度是O(n^2)

B. 散列法:将nums中的每个元素进行散列,查找特定元素时间复杂度只需O(1), 算法时间复杂度是O(n).

3. 代码实现

A. 暴力求解

int *twoSum(int *nums, int numsSize, int target) 
{
    int *ans = (int *)malloc(sizeof(int) * 2);
    int i, j;
    int tmp;
    for(i = 0; i < numsSize; ++i)
    {
        tmp = target - nums[i];
        ans[0] = i;
        for(j = i + 1; j < numsSize; ++j)
        {
            if(tmp == nums[j])
            {
                ans[1] = j;
                return ans;
            }
        }
    }
    return NULL;
}

在这里插入图片描述

B. 利用C实现散列查找


#include <stdlib.h>
typedef struct HashNode
{
    int key;
    int index;
}HashNode;

typedef struct HashMap
{
    int size;
    HashNode **storage;
}HashMap;

HashMap *create_hash(int size)
{
    HashMap *hashmap;
    hashmap = (HashMap *)malloc(sizeof(HashMap));
    assert(hashmap != NULL);
    hashmap -> size = size;
    hashmap -> storage = (HashNode **) malloc(sizeof(HashNode *) * size);
    assert(hashmap -> storage != NULL);
    /*for(int i = 0; i < size; ++i)
    {
        hashmap -> storage[i] = NULL;
    }*/
    memset(hashmap -> storage, 0, sizeof(HashNode *) * size);
    return hashmap;
}

void destory_hash(HashMap * hashmap)
{
    int i;
    for(i = 0; i < hashmap -> size; ++i)
    {
        if (hashmap -> storage[i] != NULL)
            free(hashmap -> storage[i]);
    }
    free(hashmap -> storage);
    free(hashmap);
}

void set_hash(HashMap *hashmap, int key, int index)
{
    int hash = abs(key) % hashmap -> size;
    HashNode *node;
    while((node = hashmap -> storage[hash]) != NULL)
    {
        if(hash < hashmap -> size - 1)
            ++hash;
        else
            hash = 0;
    }
    
    node = (HashNode *)malloc(sizeof (HashNode));
    assert(node != NULL);
    node -> key = key;
    node -> index = index;
    hashmap -> storage[hash] = node;
}

HashNode *get_hash(HashMap * hashmap, int key)
{
    int hash = abs(key) % hashmap -> size;
    HashNode *node;
    while((node = hashmap -> storage[hash]))
    {
        if(node -> key == key)
            return node;
        if(hash < hashmap -> size - 1)
            ++hash;
        else
            hash = 0;
    }
    return NULL;   
}


int *twoSum(int* nums, int numsSize, int target) 
{
    HashMap *hashmap;
    HashNode *node;
    int rest, i;
    int *result = (int *) malloc(sizeof(int )* 2);
    
    hashmap = create_hash(numsSize * 2);
    for(i = 0; i < numsSize; ++i)
    {
        rest = target - nums[i];
        node = get_hash(hashmap, rest);
        if(node != NULL)
        {
            result[0] = i;
            result[1] = node -> index;
            break;
        }
        else
            set_hash(hashmap, nums[i], i);
    }
    return result;
}

在这里插入图片描述

C. 利用C++的STL之map

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        map<int, int> hash;
        int i, part;
        vector<int> result;
        
        for(i = 0; i < nums.size(); ++i)
        {
            if(hash[target - nums[i]] != 0 && hash[target - nums[i]] - 1 != i)
            {
                result.push_back(hash[target - nums[i]] - 1);
                result.push_back(i);
                break;
            }
            hash[nums[i]] = i + 1;
        }
        
        return result;
    }
};

在这里插入图片描述

总结:

这是一道典型的查找题目,查找分为2种,静态查找和动态查找。静态查找只涉及查找,动态查找还涉及元素的插入和删除。常见的静态查找方法有顺序查找(暴力求解),折半查找(关键字有序),散列查找。常见的动态查找有BST(AVL是其改进), B树,B+树,散列查找。散列查找因其线性时间复杂度具有极大的吸引力,但是冲突处理比较麻烦,实际情况下很难达到线性时间复杂度。

猜你喜欢

转载自blog.csdn.net/qq_34302921/article/details/85379660