[杨小白]_leetcode_力扣第 320 场周赛-第一、二题

67 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

前言

小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标1900分,现在1806!!

力扣第 320 场周赛-力扣

第 320 场周赛 - 力扣(LeetCode)

这次可真是做大牢啊,一个半小时,12分钟就做了前两题,然后干坐一个多小时,也没做出来第三题。

image.png

2475. 数组中不等三元组的数目

给你一个下标从 0 开始的正整数数组 nums 。请你找出并统计满足下述条件的三元组 (i, j, k) 的数目:

  • 0 <= i < j < k < nums.length
  • nums[i]、nums[j] 和 nums[k] 两两不同 。
    • 换句话说:nums[i] != nums[j]、nums[i] != nums[k] 且 nums[j] != nums[k]
  • 返回满足上述条件三元组的数目。

示例 1

输入:nums = [4,4,2,4,3]

输出:3

解释:下面列出的三元组均满足题目条件:

  • (0, 2, 4) 因为 4 != 2 != 3
  • (1, 2, 4) 因为 4 != 2 != 3
  • (2, 3, 4) 因为 2 != 4 != 3

共计 3 个三元组,返回 3 。

注意 (2, 0, 4) 不是有效的三元组,因为 2 > 0 。

示例 2

输入: nums = [1,1,1,1,1]

输出: 0

解释: 不存在满足条件的三元组,所以返回 0 。

提示

  • 3 <= nums.length <= 100
  • 1 <= nums[i] <= 1000

代码

第一题1000的数据,直接暴力做。

class Solution {
    public int unequalTriplets(int[] nums) {
        int res = 0;
        for (int i = 0; i < nums.length - 2; i++) {
            for (int j = i + 1; j < nums.length - 1; j++) {
                for (int k = j+1; k < nums.length; k++) {
                    if (nums[j]!=nums[i] && nums[i]!=nums[k] && nums[j]!= nums[k]) {
                        res++;
                    }
                }
            }
        }
        return res;
    }
}

非暴力做法,复杂度O(nlogn)

class Solution {
    public int unequalTriplets(int[] nums) {
        Arrays.sort(nums);
        int ans = 0, start = 0, n = nums.length;
        for (int i = 0; i < n - 1; i++) {
            if (nums[i + 1] != nums[i]) {
                ans += start * (i - start + 1) * (n - 1 - i);
                start = i + 1;
            }
        }
        return ans;
    }
}

2476. 二叉搜索树最近节点查询

给你一个 二叉搜索树 的根节点 root ,和一个由正整数组成、长度为 n 的数组 queries 。

请你找出一个长度为 n 的 二维 答案数组 answer ,其中 answer[i] = [mini, maxi] :

  • mini 是树中小于等于 queries[i] 的 最大值 。如果不存在这样的值,则使用 -1 代替。
  • maxi 是树中大于等于 queries[i] 的 最小值 。如果不存在这样的值,则使用 -1 代替。 返回数组 answer 。

 ## 示例 1

image.png

输入:root = [6,2,13,1,4,9,15,null,null,null,null,null,null,14], queries = [2,5,16]

输出:[[2,2],[4,6],[15,-1]]

解释:按下面的描述找出并返回查询的答案:

  • 树中小于等于 2 的最大值是 2 ,且大于等于 2 的最小值也是 2 。所以第一个查询的答案是 [2,2] 。
  • 树中小于等于 5 的最大值是 4 ,且大于等于 5 的最小值是 6 。所以第二个查询的答案是 [4,6] 。
  • 树中小于等于 16 的最大值是 15 ,且大于等于 16 的最小值不存在。所以第三个查询的答案是 [15,-1] 。

示例 2

image.png

输入:root = [4,null,9], queries = [3]

输出:[[-1,4]]

解释:树中不存在小于等于 3 的最大值,且大于等于 3 的最小值是 4 。所以查询的答案是 [-1,4] 。

提示

  • 树中节点的数目在范围 [2, 105]
  • 1 <= Node.val <= 106
  • n == queries.length
  • 1 <= n <= 105
  • 1 <= queries[i] <= 106

代码

考试想的是拿到一个array里面,sort之后,自己写二分。所以写了个层序遍历

后来发现,dfs的时候,直接用中序遍历就可以不用sort了。代码放在第二段了。复杂度都是nlogn,所以相差也不大

image.png

class Solution {
        public List<List<Integer>> closestNodes(TreeNode root, List<Integer> queries) {
            ArrayList<Integer> arrayList = new ArrayList<>();
            ArrayDeque<TreeNode> treeNodes = new ArrayDeque<>();
            treeNodes.add(root);
            while (!treeNodes.isEmpty()) {
                int size = treeNodes.size();
                for (int i = 0; i < size; i++) {
                    TreeNode poll = treeNodes.poll();
                    arrayList.add(poll.val);
                    if (poll.left != null) {
                        treeNodes.add(poll.left);
                    }
                    if (poll.right != null) {
                        treeNodes.add(poll.right);
                    }
                }
            }
            Collections.sort(arrayList);
            List<List<Integer>> res = new ArrayList<>();
            for (int i = 0; i < queries.size(); i++) {
                ArrayList<Integer> arrayList1 = new ArrayList<>();
                arrayList1.add(findLow(arrayList, queries.get(i)));
                arrayList1.add(findUp(arrayList, queries.get(i)));
                res.add(arrayList1);
            }
            return res;
        }

        private Integer findUp(ArrayList<Integer> arrayList, Integer integer) {
            if (integer > arrayList.get(arrayList.size() - 1)) {
                return -1;
            }
            int l = 0;
            int r = arrayList.size();
            while (r > l) {
                int mid = r + l >> 1;
                if (arrayList.get(mid) >= integer) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            return arrayList.get(r);
        }

        private Integer findLow(ArrayList<Integer> arrayList, Integer integer) {
            if (integer < arrayList.get(0)) {
                return -1;
            }
            int l = 0;
            int r = arrayList.size() - 1;
            while (r > l) {
                int mid = r + l + 1 >> 1;
                if (arrayList.get(mid) <= integer) {
                    l = mid;
                } else {
                    r = mid - 1;
                }
            }
            return arrayList.get(r);
        }   
}
class Solution {
    public List<List<Integer>> closestNodes(TreeNode root, List<Integer> queries) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        dfs(arrayList,root);
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i < queries.size(); i++) {
            ArrayList<Integer> arrayList1 = new ArrayList<>();
            arrayList1.add(findLow(arrayList, queries.get(i)));
            arrayList1.add(findUp(arrayList, queries.get(i)));
            res.add(arrayList1);
        }
        return res;
    }
    private void dfs(ArrayList<Integer> arrayList, TreeNode root) {
        if(root == null) {
            return;
        }
        dfs(arrayList,root.left);
        arrayList.add(root.val);
        dfs(arrayList,root.right);
    }

    private Integer findUp(ArrayList<Integer> arrayList, Integer integer) {
        if (integer > arrayList.get(arrayList.size() - 1)) {
            return -1;
        }
        int l = 0;
        int r = arrayList.size();
        while (r > l) {
            int mid = r + l >> 1;
            if (arrayList.get(mid) >= integer) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return arrayList.get(r);
    }

    private Integer findLow(ArrayList<Integer> arrayList, Integer integer) {
        if (integer < arrayList.get(0)) {
            return -1;
        }
        int l = 0;
        int r = arrayList.size() - 1;
        while (r > l) {
            int mid = r + l + 1 >> 1;
            if (arrayList.get(mid) <= integer) {
                l = mid;
            } else {
                r = mid - 1;
            }
        }
        return arrayList.get(r);
    }
}

3.结束

坐大牢,不知道会不会掉分。希望早日1900。