LeetCode 1、两数之和(三种语言--c、c++、python;两种方法--暴力法、哈希表法)

一、题目描述

题目所在的地址

给定一个整数数组 n u m s nums nums 和一个目标值 t a r g e t target target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例

给定 n u m s = [ 2 , 7 , 11 , 15 ] , t a r g e t = 9 nums = [2, 7, 11, 15], target = 9 nums=[2,7,11,15],target=9

因为 n u m s [ 0 ] + n u m s [ 1 ] = 2 + 7 = 9 nums[0] + nums[1] = 2 + 7 = 9 nums[0]+nums[1]=2+7=9

所以返回 [ 0 , 1 ] [0, 1] [0,1]

二、暴力法-两遍for循环

我的第一思路是双重for循环来遍历整个数组,遍历两次数组,当外循环下标和内循环下标对应的两个数相加为target时,退出循环。


1、c语言
#include<stdio.h>
#include<malloc.h>

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

int main()
{
    int *a = NULL;
    int nums[4] = {2,7,11,15};
    int* returnS;

    a = twoSum(nums, 4, 9, returnS);
    if(*returnS == 2)
        printf("%d %d", a[0], a[1]);
    free(a);
    return 0;
}

知识点:

malloc 是c语言中的动态分配内存, int *ret = (int *)malloc(2*sizeof(int)); ,malloc函数返回的是void* 型,所以要强制类型转换成 int,在前面加上 (int *) , 才能给整型赋值,后面 (2*sizeof(int)) 的意思是分配两个 int 大小的空间。


2、c++语言
#include<iostream>
#include<vector>
using namespace std;

class Solution
{
public:
    vector<int> twoSum(vector<int>& nums, int target)
    {
        vector<int> ans;
        int temp;
        for(int i = 0; i < nums.size()-1; i++)
        {
            temp = target - nums[i];
            for(int j = i+1; j < nums.size(); j++)
            {
                if(temp == nums[j])
                {
                    ans.push_back(i);
                    ans.push_back(j);
                    return ans;
                }
            }
        }
        return ans;
    }
};

int main()
{
    vector<int> nums = {2, 7, 11, 15};
    vector<int> ans;
    Solution solu;
    ans = solu.twoSum(nums, 9);

    cout << ans[0] << " " << ans[1] << endl;
    return 0;
}

3、python
class Solution:
    def twoSum(self, nums, target):
        n = len(nums)

        for i in range(n):
            temp = target - nums[i]
            if temp in nums:
                j = nums.index(temp)
                if i == j:
                    continue
                else:
                    return i, j

if __name__ == '__main__':
    nums = [1, 2, 2, 5]
    solu = Solution()
    i, j = solu.twoSum(nums, 4)
    print i, j

三、哈希表法

哈希表方法的详述,请见下面这篇博文–详谈哈希表

1、c语言

解题思路

一个动态查找的过程。对于每一个 n u m s [ i ] nums[i] nums[i] ,我们要寻找剩下的数中是否存在 t e m p ( t e m p = t a r g e t − n u m s [ i ] ) temp(temp=target-nums[i]) temp(temp=targetnums[i]) ,最后返回的是下标。这里用哈希表来实现查找过程,如果不存在那么就在哈希表中对应位置插入一个新结点(结点记录了 n u m s [ i ] 和 i nums[i]和i nums[i]i

#include<stdio.h>
#include<malloc.h>
#include<math.h>

// 用c语言实现哈希表
struct MyNode
{
    int data;          // 存放数值
    int index;         // 用来存放下标
    struct MyNode* next;
};

struct HashTbl
{
    int TableSize;
    struct MyNode** TheLists;   // 指针的数组
};

int NextPrime(int n)            // 求不小于n的素数
{
    if(n % 2 == 0)
        n++;
    int i;
    int temp;
    for(; ; n+=2)
    {
        temp = 1;
        for(i = 3; i <= sqrt(n); i+=2)
            if(n % i == 0)
            {
                temp = 0;
                break;
            }
        if(temp)
            return n;
    }
}

int Hash(int key, int TableSize)  // 哈希函数(散列函数)
{
    int ret = abs(key) % TableSize;
    return ret;
}

struct HashTbl* InitializeTable(int TableSize)
{
    struct HashTbl* H = (struct HashTbl*)malloc(sizeof(struct HashTbl));
    int i;
    H->TableSize = NextPrime(TableSize);  // 若TableSize不是素数,则把其变为下一个素数
    H->TheLists = (struct MyNode**)malloc(sizeof(struct MyNode*)*(H->TableSize));
    for(i = 0; i<H->TableSize; i++)       // 配置表头
    {
        H->TheLists[i] = (struct MyNode *)malloc(sizeof(struct MyNode));
        H->TheLists[i]->next = NULL;
        H->TheLists[i]->index = -1;
    }
    return H;
};

struct MyNode* Find(int key, struct HashTbl* H)
{
    struct MyNode* P;
    struct MyNode* L;
    L = H->TheLists[Hash(key, H->TableSize)];
    P = L->next;
    while(P!=NULL && P->data != key)
    {
        P=P->next;
    }
    return P;
};

void Insert(int key, struct HashTbl* H, int Index)
{
    struct MyNode* Pos;
    struct MyNode* L;
    Pos = Find(key, H);
    if(Pos == NULL)
    {
        struct MyNode* NewCell = (struct MyNode*)malloc(sizeof(struct MyNode));
        L = H->TheLists[Hash(key, H->TableSize)];
        NewCell->next = L->next;
        L->next = NewCell;
        NewCell->data = key;
        NewCell->index = Index;
    }
}

void FreeHashTable(struct HashTbl* H, int TableSize)
{
    int i = 0;
    struct MyNode* temp = NULL, *deleteNode = NULL;
    for(i = 0; i< TableSize; i++)
    {
        temp = H->TheLists[i];
        while(temp)
        {
            deleteNode = temp;
            temp = temp->next;
            free(deleteNode);
        }
    }
    free(H);
}

// 基本思路:遍历数组,对于每次的值nums[i],可以得到temp=target-nums[i],
// 然后去哈希表中查找是否存在temp,若存在则输出两个数的小标,若不存在就
// 把nums[i]插入到哈希表中。
int* twoSum(int* nums, int numsSize, int target, int* returnSize)
{
    struct HashTbl* HashforIndex = InitializeTable(numsSize);
    int temp, i;
    *returnSize = 0;
    int *output = NULL;
    for(i = 0; i< numsSize; i++)
    {
        temp = target - nums[i];
        struct MyNode* findNode = Find(temp, HashforIndex);
        if(findNode != NULL)    // 找到了temp
        {
            output = (int *)malloc(2*sizeof(int));
            *returnSize = 2;
            *output = findNode->index;
            *(output + 1) = i;
            return output;
        }
        else
            Insert(nums[i], HashforIndex, i);
    }
    FreeHashTable(HashforIndex, HashforIndex->TableSize);
    return output;
}

int main()
{
    int *a = NULL;
    int nums[4] = {2,7,11,15};
    int* returnS;

    a = twoSum(nums, 4, 9, returnS);
    if(*returnS == 2)
        printf("%d %d", a[0], a[1]);
    free(a);
    return 0;
}
2、c++语言

本方法用unordered_map 底层实现的哈希表。更多的unordered_map 用法,请看c++中unordered_map的用法的详述(包含unordered_map和map的区别)

#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;

// c++: 哈希表法
// 遍历数组A{
//     对每个A[i],取得temp=target-Ai;
//     在hash表中寻找temp,一旦找到,返回;
//     如果没有找到,把temp放到hash表里
// }
class Solution{
public:
    vector<int> twoSum(vector<int>& nums, int target)
    {
        unordered_map<int, int> mymap;
        vector<int> ans;
        int temp;
        for(int i = 0; i < nums.size(); i++)
        {
            temp = target - nums[i];
            if(mymap.find(temp) != mymap.end() && mymap[temp] != i)
            {
                ans.push_back(mymap[temp]);
                ans.push_back(i);
                return ans;
            }
            else{
                mymap[nums[i]] = i;
            }
        }
        return ans;
    }
};

int main()
{
    vector<int> nums{2, 7, 11, 15};
    vector<int> ans;
    Solution sol;
    ans = sol.twoSum(nums, 9);
    if(!ans.empty())
        cout << ans[0] << ' ' << ans[1] << endl;
    return 0;

}
3、python

这里通过字典来模拟哈希表查找过程。

class Solution:
    def twoSum(self, nums, tatget):
        mymap = {}
        for index, num in enumerate(nums):
            mymap[num] = index
        for i in range(len(nums)):
            temp = tatget - nums[i]
            if mymap.get(temp) is not None and i != mymap.get(temp):
                return i, mymap.get(temp)

if __name__ == '__main__':
    nums = [1, 2, 2, 5]
    solu = Solution()
    i, j = solu.twoSum(nums, 4)
    print(i, j)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值