两数之和

leetcode 1 号算法题:两数之和
leetcode 167 号算法题:两数之和Ⅱ - 输入有序数组
leetcode 170 号算法题:两数之和Ⅲ - 数据结构设计
leetcode 653 号算法题:两数之和Ⅳ - 输入 BST
leetcode 15 号算法题:三数之和
leetcode 18 号算法题:四数之和

培养算法思维【逐渐优化,一直到最优】提升编程内功 - 两数之和

leetcode 1 号算法题:两数之和

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

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

class Solution {
    public int[] twoSum(int[] nums, int target) {
        if(nums==null||nums.length<=0)
            return new int[0];
        int n=nums.length;
        Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<n;i++){
            int x=nums[i];
            if(map.containsKey(target-x)){
                int index=map.get(target-x);
                return new int[]{i,index};
            }
            map.put(x,i);
        }
        return new int[0];
    }
}

leetcode 167 号算法题:两数之和Ⅱ - 输入有序数组

给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。

函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。

你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        if(numbers==null||numbers.length<=0)
        return new int[0];
        for(int i=0;i<numbers.length;i++){
            int x=numbers[i];
            int index=binarySearch(i+1,numbers.length-1,numbers,target-x);
            if(index!=-1)
            return new int[]{i+1,index+1};
        }
        return new int[0];
    }
    private int binarySearch(int left,int right,int [] numbers,int target){
        while(left<=right){
            int mid=(left+right)/2;
            if(numbers[mid]==target)
                return mid;
            else if(numbers[mid]>target)
                right=mid-1;
            else
                left=mid+1;
        }
        return -1;
    }
}

leetcode 170 号算法题:两数之和Ⅲ - 数据结构设计

设计一个接收整数流的数据结构,该数据结构支持检查是否存在两数之和等于特定值。

实现 TwoSum 类:

TwoSum() 使用空数组初始化 TwoSum 对象
void add(int number) 向数据结构添加一个数 number
boolean find(int value) 寻找数据结构中是否存在一对整数,使得两数之和与给定的值相等。如果存在,返回 true ;否则,返回 false
O(nlogn)方法:

class TwoSum {
    private List<Integer> list;
    boolean isSorted;
    /** Initialize your data structure here. */
    public TwoSum() {
        list=new ArrayList<>();
        isSorted=false;
    }
    
    /** Add the number to an internal data structure.. */
    public void add(int number) {
        list.add(number);
        isSorted=false;
    }
    
    /** Find if there exists any pair of numbers which sum is equal to the value. */
    public boolean find(int value) {
        if(isSorted==false){
            Collections.sort(list);
            isSorted=true;
        }
        int left=0;
        int right=list.size()-1;
        while(left<right){
            int sum=list.get(left)+list.get(right);
            if(sum==value){
                return true;
            }else if(sum<value){
                left++;
            }else{
                right--;
            }
        }
        return false;
    }
}

O(n)方法:

class TwoSum {
    Map<Integer,Integer> map;
    /** Initialize your data structure here. */
    public TwoSum() {
        map=new HashMap<>();
    }
    
    /** Add the number to an internal data structure.. */
    public void add(int number) {
        map.put(number,map.getOrDefault(number,0)+1);
    }
    
    /** Find if there exists any pair of numbers which sum is equal to the value. */
    public boolean find(int value) {
        for(Integer num:map.keySet()){
            int target=value-num;
            if(num==target&&map.get(target)>1)return true;
            if(num!=target&&map.containsKey(target))return true;
        }
        return false;
    }
}

leetcode 653 号算法题:两数之和Ⅳ - 输入 BST

class Solution {
    public boolean findTarget(TreeNode root, int k) {
        List<Integer> list=new ArrayList<>();
        if(root==null)
        return false;
        inOrder(root,list);
        int left=0,right=list.size()-1;
        while(left<right){
            int sum=list.get(left)+list.get(right);
            if(sum==k){
                return true;
            }else if(sum<k){
                left++;
            }else{
                right--;
            }
        }
        return false;
    }
    private void inOrder(TreeNode root,List<Integer> list){
        if(root!=null){
            inOrder(root.left,list);
            list.add(root.val);
            inOrder(root.right,list);
        }
    }
}

leetcode 15 号算法题:三数之和

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        if(nums==null||nums.length<=0)
        return new ArrayList<>();
        Set<List<Integer>> set=new HashSet<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            int value=-nums[i];
            int left=i+1,right=nums.length-1;
            while(left<right){
                int sum=nums[left]+nums[right];
                if(sum==value){
                    set.add(Arrays.asList(value*-1,nums[left],nums[right]));
                    left++;
                    right--;
                }else if(sum>value){
                    right--;
                }else{
                    left++;
                }
            }
        }
        return new ArrayList<>(set);

    }
}

leetcode 18 号算法题:四数之和

错误:

class Solution {
    private List<List<Integer>> threeSum(int[] nums,int target,int begin,int end){
        Set<List<Integer>> three_set=new HashSet<>();
        for(int i=begin;i<end;i++){
            int value=target-nums[i];
            int left=begin+1,right=end;
            while(left<right){
                int sum=nums[left]+nums[right];
                if(sum==value){
                    three_set.add(Arrays.asList(value*-1,nums[left],nums[right]));
                    left++;
                    right--;
                }else if(sum<value){
                    left++;
                }else{
                    right--;
                }
            }
        }
        return new ArrayList<>(three_set);
    }
    public List<List<Integer>> fourSum(int[] nums, int target) {
        if(nums==null||nums.length<=0)
        return new ArrayList<>();
        Set<List<Integer>> four_set=new HashSet<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            int value=target-nums[i];
            int left=i+1,right=nums.length-1;
            List<List<Integer>> list=threeSum(nums,value,left,right);
            if(!list.isEmpty()){
                for(int j=0;j<list.size();j++){
                    List<Integer> list_temp=list.get(j);
                    list_temp.add(value*-1);
                    four_set.add(list_temp);
                }
            }
        }
        return new ArrayList<>(four_set);
    }
}

正确:

public List<List<Integer>> fourSum(int[] nums, int target) {
    if (nums == null || nums.length < 4)
        return new ArrayList<>();

    Arrays.sort(nums);

    List<List<Integer>> res = new ArrayList<>();

    // O(n^3)
    for (int i = 0; i < nums.length - 3; i++) {
        // 忽略后面与前面重复的元素
        if (i > 0 && nums[i] == nums[i - 1]) continue;

        for (int j = i + 1; j < nums.length - 2; j++) {
            // 忽略后面与前面重复的元素
            if (j > i + 1 && nums[j] == nums[j - 1]) continue;

            int partSum = nums[i] + nums[j];
            int left = j + 1;
            int right = nums.length - 1;

            while (left < right) {
                int sum = partSum + nums[left] + nums[right];

                if (sum > target) {
                    right--;
                } else if (sum < target) {
                    left++;
                } else {
                    res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                    while (left < right && nums[left] == nums[++left]);
                    while (left < right && nums[right] == nums[--right]);
                }
            }
        }
    }

    return res;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值