LeetCode-Two Sum

本文介绍了一种高效的方法来解决两数之和问题,通过使用哈希表,将时间复杂度降低到O(n)。具体步骤包括初始化哈希表,遍历数组并查找目标值减去当前元素的值是否在哈希表中,从而快速找到答案。

题目:https://oj.leetcode.com/problems/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

分析:

方法1:暴力,复杂度O(n2),会超时
方法2:hash。用一个哈希表,存储每个数对应的下标,复杂度O(n).
方法3:先排序,然后左右夹逼,排序O(n log n),左右夹逼O(n),最终O(n log n)。但是注意,这题需要返回的是下标,而不是数字本身,因此这个方法行不通。

源码:Java版本
算法分析:用一个哈希表,存储每个数对应的下标。时间复杂度O(n),空间复杂度O(n)

public class Solution {
    public int[] twoSum(int[] numbers, int target) {
        Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<numbers.length;i++) {
            map.put(numbers[i],i+1);
        }
        
        int[] result=new int[2];
        int other;
        for(int i=0;i<numbers.length;i++) {
            other=target-numbers[i];
            if(map.containsKey(other) && i+1<map.get(other)) {
                result[0]=i+1;
                result[1]=map.get(other);
                break;
            }
        }
        return result;
    }
}

LeetCode 中,two-sum 问题是经典的算法问题之一。使用哈希表解法是其中一种高效且常见的实现方式。该方法的时间复杂度为 O(n),空间复杂度也为 O(n),相较于暴力双重循环的 O(n&sup2;) 方法更优。 ### 哈希表解法的核心思想 通过遍历数组,在每次迭代中计算当前元素与目标值之间的差值(即 `target - nums[i]`),然后检查该差值是否已经存在于哈希表中。如果存在,则说明找到了满足条件的两个数;如果不存在,则将当前元素及其索引存入哈希表中,以便后续查找。 ### C++ 实现代码 ```cpp class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int, int> hash; // 存储元素的值和下标 int n = nums.size(); for (int i = 0; i < n; ++i) { int x = target - nums[i]; // 寻找对应的另一个加数 if (hash.count(x)) return { hash[x], i }; // 如果找到,直接返回结果 else hash[nums[i]] = i; // 否则,将当前元素存入哈希表 } return { -1, -1 }; // 没有找到符合条件的两个数 } }; ``` ### C 实现代码 另一种实现方式是使用静态分配或动态分配的哈希表结构,例如使用数组模拟哈希表。这种方法在某些特定条件下可能效率更高,尤其是当输入数据范围较小且已知时。 以下是一个优化过的 C 语言实现示例: ```c int* twoSum(int* nums, int numsSize, int target, int* returnSize) { int min = INT_MAX; *returnSize = 2; int i = 0; for (i = 0; i < numsSize; i++) { if (nums[i] < min) min = nums[i]; } int max = target - min; int len = max - min + 1; // 确定哈希表长度 if (len <= 50000) { int *table = (int*)malloc(len * sizeof(int)); int *indice = (int*)malloc(2 * sizeof(int)); for (i = 0; i < len; i++) { table[i] = -1; // 初始化哈希表 } for (i = 0; i < numsSize; i++) { if (nums[i] - min < len) { if (table[target - nums[i] - min] != -1) { indice[0] = table[target - nums[i] - min]; indice[1] = i; return indice; } table[nums[i] - min] = i; } } free(table); return indice; } else { int *a = (int *)malloc(sizeof(int) * 2); for (int i = 0; i < numsSize; i++) { for (int j = 0; j < numsSize; j++) { if (i != j && nums[i] + nums[j] == target) { a[0] = i; a[1] = j; return a; } } } return NULL; } } ``` ### 关键点分析 - **时间复杂度**:O(n),因为每个元素只被处理一次。 - **空间复杂度**:O(n),用于存储哈希表。 - **适用场景**:适用于需要快速查找配对值的问题。 - **注意事项**:确保在查找过程中不会重复使用同一个元素,因此需在哈希表中保存的是之前遍历过的元素[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值