剑指 Offer II 056. 二叉搜索树中两个节点之和 / 剑指 Offer II 057. 值和下标之差都在给定的范围内

剑指 Offer II 056. 二叉搜索树中两个节点之和【简单题】

思路:【递归】

递归中序遍历BST,将中序遍历的每个节点的值存入list集合,最后得到的list集合是一个递增的集合,遍历list集合每一个元素,然后倒序遍历后边的元素,搜索是否有符合条件的情况。

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean findTarget(TreeNode root, int k) {
        List<Integer> list = new ArrayList<>();
        dfs(root,list);
        int size = list.size(), left = 0,right = size - 1;
        while (left < size){
            for (int i = right; i > left; i--) {
                int sum = list.get(left) + list.get(i);
                if (sum == k){
                    return true;
                }else if (sum < k){
                    break;
                }
            }
            left++;
        }
        return false;
    }
    public static void dfs(TreeNode root,List<Integer> list){
        if (root == null){
            return;
        }
        dfs(root.left,list);
        list.add(root.val);
        dfs(root.right,list);
    }
}

剑指 Offer II 057. 值和下标之差都在给定的范围内【中等题】

思路:

将桶的大小定为 t + 1,那么如果两个元素同属一个桶,则必然符合 元素差的绝对值小于等于 t 这一条件;或者如果两个元素属于相邻桶,那么只要当前遍历到的元素与相邻桶中的元素 满足差的绝对值小于等于 t ,也可满足 元素差的绝对值小于等于 t 这一条件。 将遍历到的当前元素和其对应的桶id存入map,当 i >= k 时,移除掉 mapid为在数组 nums 中 下标为中 i - k 的元素对应的值,以求满足下标的差的绝对值小于等于 k

代码:

class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        int n = nums.length;
        Map<Long,Long> map = new HashMap<>();
        //根据 t 求出桶的宽度
        long w = (long) t + 1;
        //遍历数组中每个元素
        for (int i = 0; i < n; i++) {
            //获取当前元素的桶id
            long id = getID(nums[i], w);
            //如果 map 中 已经存在 当前 id 说明这个桶里 有 符合条件的元素,返回 true
            if (map.containsKey(id)){
                return true;
            }
            //如果 map 中 id 左侧的桶里有符合条件的元素 返回 true
            if (map.containsKey(id-1) && Math.abs(nums[i]-map.get(id-1)) < w){
                return true;
            }
            //如果 map 中 id 右侧的桶里有符合条件的元素 返回true
            if (map.containsKey(id+1) && Math.abs(nums[i]-map.get(id+1)) < w){
                return true;
            }
            //如果以上三种情况均不满足 则 将 当前元素及其对应的桶 id 放入 map 中
            map.put(id,(long) nums[i]);
            //将 map 中 下标比i小k的元素 对应的 id 删掉
            if (i >= k){
                map.remove(getID(nums[i-k], w));
            }
        }
        return false;
    }
    /**
     * 获取传入元素的桶id
     * @param x  传入元素
     * @param w  桶的宽度
     * @return 桶id
     */
    public static long getID(long x,long w){
        if (x >= 0){
            return x / w;
        }
        return (x + 1) / w - 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值