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

leetcode1. 两数之和

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


class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map 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]

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);
    }
}

你可能感兴趣的:(算法)