从leetcode1. 两数之和循序渐进(双指针,BST,哈希表)

leetcode1. 两数之和

1.之前只知道桶排序那种标志数组,所以看到第一眼就想到那个方面去了。但在本题数组里面存储某个数出现的次数对该题是没有意义的,应该存储某个数出现的位置
2.哈希表是优化遍历数组寻找某个数的很好方法,看情况需要改数的值还是位置决定其中的value是什么


class Solution {
    public int[] twoSum(int[] nums, int target) {
        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 left = target - nums[i];
            if (map.containsKey(left) && map.get(left) != i) {
                return new int[] { i, map.get(left) };
            }
        }
        return new int[] { -1, -1};
    }
}


167.两数之和 II - 输入有序数组

其实是比两数之和更容易的题,可以照搬两数之和的算法,但是没有利用其有序的条件。
所以利用双指针的方法,利用其有序的条件,只要数组有序,就应该想到双指针技巧

对于双指针的应用环境的补充:
双指针技巧再分为两类,一类是「快慢指针」,一类是「左右指针」。
前者解决主要解决链表中的问题,比如典型的判定链表中是否包含环;
后者主要解决**数组(或者字符串)**中的问题,比如二分查找。
因为链表不能倒退而数组可以倒退,能倒退才使得前后指针有意义,不然就只能左右指针

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int st=0;
        int end=numbers.length-1;
        while(end>st){
            if(numbers[st]+numbers[end]==target)
            return new int[]{st+1,end+1};
            if(numbers[st]+numbers[end]>target)
            end--;
            if(numbers[st]+numbers[end]<target)
            st++;        
        }        
        return new int[] { -1, -1 };
    }
}

653.两数之和 IV - 输入 BST

不难,但是尽量利用BST的性质才能得到不错的复杂度。
之前两题的实验可知利用双指针会优于Hashmap,但是多了个条件,即需要数组有序,对于BST,进行中序遍历即可得到有序数组。再双指针即可

public class Solution {
    public boolean find(TreeNode root, int k) {
        List < Integer > list = new ArrayList();
        helper(root, list);
        int l = 0, r = list.size() - 1;
        while (l < r) {
            int sum = list.get(l) + list.get(r);
            if (sum == k)
                return true;
            if (sum < k)
                l++;
            else
                r--;
        }
        return false;
    }
    public void helper(TreeNode root, List < Integer > list) {
        if (root == null)
            return;
        helper(root.left, list);
        list.add(root.val);
        helper(root.right, list);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值