第一题:两数之和

LeetCode 第一道题目 “两数之和”(Two Sum)的详细解题思路和三种语言的实现如下:

题目描述

给定一个整数数组 nums 和一个整数 target,请你在数组中找出和为 target 的两个数,并返回它们的数组下标。

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

你可以按任意顺序返回答案。

解题思路

我们可以使用以下方法来解决这个问题:

  1. 暴力法:使用两个嵌套的循环遍历所有可能的两数组合,检查是否有两个数的和等于 target。时间复杂度是 O(n^2),空间复杂度是 O(1)。

  2. 哈希表法:利用哈希表存储每个元素及其下标。在遍历数组时,计算 target - nums[i],然后检查这个值是否已经在哈希表中。如果在哈希表中找到了,则找到了满足条件的两个数,可以立即返回它们的下标。时间复杂度是 O(n),空间复杂度是 O(n),因为哈希表的插入和查找操作的平均时间复杂度是 O(1)。

C 语言实现

#include <stdio.h>
#include <stdlib.h>

#define HASH_SIZE 10000

// 哈希表节点
typedef struct {
    int key;
    int value;
} HashNode;

// 哈希表
typedef struct {
    HashNode* table[HASH_SIZE];
} HashMap;

// 初始化哈希表
void initHashMap(HashMap* map) {
    for (int i = 0; i < HASH_SIZE; i++) {
        map->table[i] = NULL;
    }
}

// 哈希函数
int hash(int key) {
    return abs(key) % HASH_SIZE;
}

// 插入哈希表
void insert(HashMap* map, int key, int value) {
    int index = hash(key);
    HashNode* node = (HashNode*)malloc(sizeof(HashNode));
    node->key = key;
    node->value = value;
    map->table[index] = node;
}

// 查找哈希表
int search(HashMap* map, int key) {
    int index = hash(key);
    return map->table[index] ? map->table[index]->value : -1;
}

// 两数之和
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    HashMap map;
    initHashMap(&map);
    int* result = (int*)malloc(2 * sizeof(int));
    *returnSize = 2;

    for (int i = 0; i < numsSize; i++) {
        int complement = target - nums[i];
        int index = search(&map, complement);
        if (index != -1) {
            result[0] = index;
            result[1] = i;
            return result;
        }
        insert(&map, nums[i], i);
    }
    return NULL;
}

int main() {
    int nums[] = {2, 7, 11, 15};
    int target = 9;
    int returnSize;
    int* result = twoSum(nums, 4, target, &returnSize);
    if (result) {
        printf("Indices: %d, %d\n", result[0], result[1]);
        free(result);
    }
    return 0;
}

Java 实现

import java.util.HashMap;
import java.util.Map;

public class TwoSum {
    public static int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            if (map.containsKey(complement)) {
                return new int[] { map.get(complement), i };
            }
            map.put(nums[i], i);
        }
        throw new IllegalArgumentException("No two sum solution");
    }

    public static void main(String[] args) {
        int[] nums = {2, 7, 11, 15};
        int target = 9;
        int[] result = twoSum(nums, target);
        System.out.println("Indices: " + result[0] + ", " + result[1]);
    }
}

Python 实现

def two_sum(nums, target):
    num_to_index = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in num_to_index:
            return [num_to_index[complement], i]
        num_to_index[num] = i
    raise ValueError("No two sum solution")

# 示例使用
nums = [2, 7, 11, 15]
target = 9
result = two_sum(nums, target)
print(f"Indices: {result[0]}, {result[1]}")

时间复杂度

  • 暴力法

    • 时间复杂度:O(n^2)
    • 空间复杂度:O(1)
  • 哈希表法

    • 时间复杂度:O(n)
    • 空间复杂度:O(n)

总结

  • 暴力法:时间复杂度较高,但实现简单。适合数据量小的情况。
  • 哈希表法:时间复杂度较低,适合数据量大的情况,使用哈希表可以显著提高效率。
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰魄雕狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值