LeetCode-01目标和对应两个数字的下标(多种解法)

文章提供了解决方案,给定一个数组和目标和,找到数组中两个数的下标,使得它们的和等于目标值。解法包括双指针法(两层循环)和哈希表法(单层循环),哈希表法通过牺牲空间来降低时间复杂度至线性级别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 *  题目描述:给定⼀个数组和⼀个⽬标和,从数组中找两个数字相加等于⽬标和,输出这两个数字的下标。
 *  其中两数之和等于目标数, 只有一解
 *  难度:简单
 */
public class Test01 {
    public static void main(String[] args) {
        int[] nums = {11,15,2,7};
        int target = 9;
        int[] ints1 = twoSum01(nums, target);
        int[] ints2 = twoSum02(nums, target);
        int[] ints3 = twoSum03(nums, target);
        System.out.println(Arrays.toString(ints1));
        System.out.println(Arrays.toString(ints2));
        System.out.println(Arrays.toString(ints3));
    }

    /**
     *  解法一:循环, 两个指针, 从左到右移动依次相加判断是否相等
     *  双层循环
     *      时间复杂度:两层 for 循环,O(n²)
     *      空间复杂度:O(1)
     * @param nums
     * @param target
     */
    public static int[] twoSum01(int[] nums, int target){
        int [] ans = null;
        for(int i=0; i< nums.length -1; i++) {
            for(int j = (i+1);j< nums.length; j++){
                if(nums[i]+nums[j] == target) {
                    ans=new int[2];
                    ans[0] = i;
                    ans[1] = j;
                    return ans;
                }
            }
        }
        return ans;
    }

    /**
     * 解法二: 双层循环 改成单层循环, map 记录值和下标的信息
     * 时间复杂度:⽐解法⼀少了⼀个 for 循环,降为 O(n)
     * 空间复杂度:所谓的空间换时间,这⾥就能体现出来, 开辟了⼀个 hash table ,空间复杂度变为 O(n)
     *
     * sub=target-nums[i]
     * if(nums[j]==sub){}
     * 有没有⼀种⽅法,不⽤遍历就可以找到元素⾥有没有等于 sub 的?
     * hash table !!!
     * 我们可以把数组的每个元素保存为 hash 的 key,下标保存为 hash 的 value
     * 另外排除重复使用同一个元素, 也就是本身
     * @param nums
     * @param target
     * @return
     */
    public static int[] twoSum02(int[] nums, int target){
        int [] ans = null;
        Map<Integer,Integer> map=new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i], i);
        }
        for (int i = 0; i < nums.length; i++) {
            int sub = target - nums[i];
            if (map.containsKey(sub) && map.get(sub)!=i) {
                ans=new int[2];
                ans[0] = i;
                ans[1] = map.get(sub);
                return ans;
            }
        }
        return ans;
    }

    /**
     * 解法三: 优化解法二,变为一个for
     * 变化
     * 仅仅是不需要判断是不是当前元素了,因为当前元素还没有添加进 hash ⾥
     * @param nums
     * @param target
     * @return
     */
    public static int[] twoSum03(int[] nums, int target){
        int [] ans = null;
        Map<Integer,Integer> map=new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int sub = target - nums[i];
            if (map.containsKey(sub)) {
                ans=new int[2];
                ans[0] = i;
                ans[1] = map.get(sub);
                return ans;
            }
            map.put(nums[i], i);
        }
        return ans;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值