两数之和-leetcode

题目描述(哈希表)

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

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

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

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

解法一

思路:

保存原有数组,和创建一个新的数组,新的数组是原数组通过快速排序得来的。两个指针 i,j,利用两个循环,从i元素开始,j从i+1开始,如果两数之和等于target,则推出循环,输出;若不匹配,则j向后。若遍历结束,都不匹配,则i+1,继续重复执行。

代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class leetcode_001 {
    public static int[] twoSum(int[] nums, int target) {
        int[] original=new int[nums.length];
        for(int i=0;i<nums.length;i++){
            original[i]=nums[i];
        }
        int[] result=new int[2];
        quickSort(nums,0,nums.length-1);

        int sum=0;
        for(int i=0;i<nums.length;i++){
            for(int j=i+1;j<nums.length&&i!=j;j++){
                sum=nums[i]+nums[j];
                if(sum==target){
                    result=search_index(original,nums[i],nums[j]);
                    break;
                }
            }
        }
        return result;
    }
    public static int[] search_index(int[] nums,int i,int j ) {
        int count=0;
        int[] res=new int[2];
        for(int k=0;k<nums.length;k++){
            if(count==2)break;
            if(nums[k]==i||nums[k]==j){
                res[count++]=k;
            }
        }
        return res;
    }

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String[] line = sc.nextLine().split(" ");
        int[] nums = Arrays.stream(line).mapToInt(Integer::parseInt).toArray(); //转换为int数组
        int target = sc.nextInt();
        sc.close();
        int[] result = twoSum(nums,target);
        for(int i:result)
            System.out.print(i+" ");

    }

    //快速排序主方法
    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            // 获取分区点索引
            int pi = partition(arr, low, high);
            // 递归排序左半部分
            quickSort(arr, low, pi - 1);
            // 递归排序右半部分
            quickSort(arr, pi + 1, high);
        }
    }

    //分区函数
    private static int partition(int[] arr, int low, int high) {
        // 选择最后一个元素作为基准
        int pivot = arr[high];
        // 指向小于基准区域的最后一个元素
        int i = low - 1;
        // 遍历数组,将小于基准的元素交换到左侧区域
        for (int j = low; j < high; j++) {
            if (arr[j] <= pivot) {
                i++;
                // 交换元素
                swap(arr, i, j);
            }
        }
        // 将基准元素放到正确位置
        swap(arr, i + 1, high);
        return i + 1; // 返回基准的最终位置
    }
    //交换元素
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

解法二

思路:

使用哈希表,从哈希表中寻找target-nums[i]的值的索引。创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,若存在,则输出该target-x的值所在的索引,若不存在,则将该值和索引加入到哈希表中。

代码:

import java.util.*;

class leetcode_001 {
    // 使用哈希表,用空间换时间
    public static int[] twoSum(int[] nums, int target) {
      Map<Integer, Integer> map = new HashMap<>();
      for (int i = 0; i < nums.length; i++) {
          if (map.containsKey(target - nums[i])) {
              return new int[]{map.get(target - nums[i]), i};
          }
          map.put(nums[i], i);
      }
      return new int[0];
    }


    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String[] line = sc.nextLine().split(" ");
        int[] nums = Arrays.stream(line).mapToInt(Integer::parseInt).toArray(); //转换为int数组
        int target = sc.nextInt();
        sc.close();
        int[] result = twoSum(nums,target);
        for(int i:result)
            System.out.print(i+" ");
    }
}
posted @ 2025-09-04 21:18  狐狸胡兔  阅读(13)  评论(0)    收藏  举报