LeetCode283场周赛

简介: LeetCode283场周赛

6016. Excel 表中某个范围内的单元格

Excel 表中的一个单元格 (r, c) 会以字符串 "<col><row>" 的形式进行表示,其中:

  • 即单元格的列号`c`用英文字母表中的字母标识。 - 例如,第 `1` 列用 `'A'` 表示,第 `2` 列用 `'B'` 表示,第 `3` 列用 `'C'` 表示,以此类推。
  • <row> 即单元格的行号 r 。第 r 行就用 整数r 标识。

给你一个格式为 "<col1><row1>:<col2><row2>" 的字符串 s ,其中 <col1> 表示 c1 列,<row1> 表示 r1 行,<col2> 表示 c2 列,<row2> 表示 r2 行,并满足 r1 <= r2c1 <= c2

找出所有满足 r1 <= x <= r2c1 <= y <= c2 的单元格,并以列表形式返回。单元格应该按前面描述的格式用 字符串 表示,并以 非递减 顺序排列(先按列排,再按行排)。

示例 1:

输入:s = "K1:L2"
输出:["K1","K2","L1","L2"]
解释:
上图显示了列表中应该出现的单元格。
红色箭头指示单元格的出现顺序。

示例 2:

输入:s = "A1:F1"
输出:["A1","B1","C1","D1","E1","F1"]
解释:
上图显示了列表中应该出现的单元格。 
红色箭头指示单元格的出现顺序。

提示:

  • s.length == 5
  • 'A' <= s[0] <= s[3] <= 'Z'
  • '1' <= s[1] <= s[4] <= '9'
  • s 由大写英文字母、数字、和 ':' 组成

解题思路:

直接模拟,注意数字字符转成数字要减去′ 0 ′ '0'0

class Solution {
    public List<String> cellsInRange(String s) {
        int n = s.length();
        String[] str = s.split(":");
        int r1 = str[0].charAt(1) - '0';
        int r2 = str[1].charAt(1) - '0';
        int c = (str[1].charAt(0) - str[0].charAt(0));
        List<String> res = new ArrayList<>();
        for (int i = 0; i <= c; i++) {
            char c1 = (char) (str[0].charAt(0) + i);
            for (int j = 0; j  <= r2 - r1; j++) {
                int num = (int) (str[0].charAt(1) - '0') + j;
                String ss = new String("" + c1 + num);
                res.add(ss);
            }
        }
        return res;
    }
}

6017. 向数组中追加 K 个整数

给你一个整数数组 nums 和一个整数 k 。请你向 nums 中追加 k 出现在 nums 中的、互不相同 整数,并使结果数组的元素和 最小

返回追加到 nums 中的 k 个整数之和。

示例 1:

输入:nums = [1,4,25,10,25], k = 2
输出:5
解释:在该解法中,向数组中追加的两个互不相同且未出现的正整数是 2 和 3 。
nums 最终元素和为 1 + 4 + 25 + 10 + 25 + 2 + 3 = 70 ,这是所有情况中的最小值。
所以追加到数组中的两个整数之和是 2 + 3 = 5 ,所以返回 5 。

示例 2:

输入:nums = [5,6], k = 6
输出:25
解释:在该解法中,向数组中追加的两个互不相同且未出现的正整数是 1 、2 、3 、4 、7 和 8 。
nums 最终元素和为 5 + 6 + 1 + 2 + 3 + 4 + 7 + 8 = 36 ,这是所有情况中的最小值。
所以追加到数组中的两个整数之和是 1 + 2 + 3 + 4 + 7 + 8 = 25 ,所以返回 25 。

提示:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i], k <= 10^9

解题思路:由于这个题目要求的是互 不 相 同 且 未 出 现 的 正 整 数 的 和 互不相同且未出现的正整数的和,因此连续正整数的和可以用到高斯求和公式,就不需要去模拟每次插入的是哪几个数字了,可以直接求连续数字的和。

  1. image.png
class Solution {
    public long minimalKSum(int[] nums, int k) {
        long res = 0;
        int n = nums.length;
        int pre = 0;
        Arrays.sort(nums);
        for (int i = 0; i < n; i++) {
            if (nums[i] - pre > k) {
                res += (long) ((pre + 1) + (pre + k)) * k / 2;
                return res;
            } else if (nums[i] - pre <= 1) {
                pre = nums[i];
            } else {
                res += (long) ((pre + 1) + (nums[i] - 1)) * (nums[i] - pre - 1) / 2;
                k -= (nums[i] - pre - 1);
                pre = nums[i];
            }
        }
        if (k > 0) {
            res += (long) (nums[n - 1] + 1 + nums[n - 1] + k) * k / 2;
        }
        return res;
    }
}

6018. 根据描述创建二叉树

给你一个二维整数数组 descriptions ,其中 descriptions[i] = [parenti, childi, isLefti] 表示 parentichildi二叉树 中的 父节点,二叉树中各节点的值 互不相同 。此外:

  • 如果 isLefti == 1 ,那么 childi 就是 parenti 的左子节点。
  • 如果 isLefti == 0 ,那么 childi 就是 parenti 的右子节点。

请你根据 descriptions 的描述来构造二叉树并返回其 根节点

测试用例会保证可以构造出 有效 的二叉树。

示例 1:

输入:descriptions = [[20,15,1],[20,17,0],[50,20,1],[50,80,0],[80,19,1]]
输出:[50,20,80,15,17,19]
解释:根节点是值为 50 的节点,因为它没有父节点。
结果二叉树如上图所示。

示例 2:

输入:descriptions = [[1,2,1],[2,3,0],[3,4,1]]
输出:[1,2,null,null,3,4]
解释:根节点是值为 1 的节点,因为它没有父节点。 
结果二叉树如上图所示。 

提示:

  • 1 <= descriptions.length <= 104
  • descriptions[i].length == 3
  • 1 <= parenti, childi <= 10^5
  • 0 <= isLefti <= 1
  • descriptions 所描述的二叉树是一棵有效二叉树

这个题也可以用并查集去做,主要是把对应的结点关联起来

/**
 * 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 TreeNode createBinaryTree(int[][] descriptions) {
        Map<Integer, TreeNode> map = new HashMap<>();
        for (int[] num : descriptions) {
            if (num[2] == 0) {
                map.computeIfAbsent(num[0], t -> new TreeNode(num[0])).right = map.computeIfAbsent(num[1], t -> new TreeNode(num[1]));
            } else {
                map.computeIfAbsent(num[0], t -> new TreeNode(num[0])).left = map.computeIfAbsent(num[1], t -> new TreeNode(num[1]));
            }
        }
        // 把computeIfAbsent过程中额外引入的num[1]的映射关系去掉
        for (int[] num : descriptions) {
            map.remove(num[1]);
        }
        // values集合中迭代器的第一个
        return map.values().iterator().next();
    }
}

参考: https://leetcode-cn.com/problems/create-binary-tree-from-descriptions/solution/java-yong-liao-yi-xia-bing-cha-ji-by-xia-aw9f/

* 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 TreeNode createBinaryTree(int[][] descriptions) {
        // 缓存TreeNode节点
        Map<Integer, TreeNode> map = new HashMap<>();
        DSU dsu = new DSU(100001);
        for (int[] d : descriptions) {
            TreeNode node1 = map.compute(d[0], (key, value) -> value == null ? new TreeNode(d[0]) : value);
            TreeNode node2 = map.compute(d[1], (key, value) -> value == null ? new TreeNode(d[1]) : value);
            if (d[2] ==1) {
                node1.left = node2;
            } else {
                node1.right = node2;
            }
            dsu.union(d[1], d[0]);
        }
        // 随便找一个节点即可,因为全部处理之后,所有节点的parent都是根节点
        return map.get(dsu.find(descriptions[0][0]));
    }
    class DSU {
        int[] parent;
        public DSU(int N) {
            parent = new int[N];
            for (int i = 0; i < N; ++i) {
                parent[i] = i;
            }
        }
        public int find(int x) {
            if (parent[x] != x) {
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }
        public void union(int x, int y) {
            parent[find(x)] = find(y);
        }
    }
}

6019.替换数组中的非互质数

给你一个整数数组 nums 。请你对数组执行下述操作:

  1. nums 中找出 任意 两个 相邻非互质 数。
  2. 如果不存在这样的数,终止 这一过程。
  3. 否则,删除这两个数,并 替换 为它们的 最小公倍数(Least Common Multiple,LCM)。
  4. 只要还能找出两个相邻的非互质数就继续 重复 这一过程。

返回修改后得到的 最终 数组。可以证明的是,以 任意 顺序替换相邻的非互质数都可以得到相同的结果。

生成的测试用例可以保证最终数组中的值 小于或者等于108

两个数字 xy 满足 非互质数 的条件是:GCD(x, y) > 1 ,其中 GCD(x, y)xy最大公约数

示例 1 :

输入:nums = [6,4,3,2,7,6,2]
输出:[12,7,6]
解释:
- (6, 4) 是一组非互质数,且 LCM(6, 4) = 12 。得到 nums = [12,3,2,7,6,2] 。
- (12, 3) 是一组非互质数,且 LCM(12, 3) = 12 。得到 nums = [12,2,7,6,2] 。
- (12, 2) 是一组非互质数,且 LCM(12, 2) = 12 。得到 nums = [12,7,6,2] 。
- (6, 2) 是一组非互质数,且 LCM(6, 2) = 6 。得到 nums = [12,7,6] 。
现在,nums 中不存在相邻的非互质数。
因此,修改后得到的最终数组是 [12,7,6] 。
注意,存在其他方法可以获得相同的最终数组。

示例 2 :

输入:nums = [2,2,1,1,3,3,3]
输出:[2,1,1,3]
解释:
- (3, 3) 是一组非互质数,且 LCM(3, 3) = 3 。得到 nums = [2,2,1,1,3,3] 。
- (3, 3) 是一组非互质数,且 LCM(3, 3) = 3 。得到 nums = [2,2,1,1,3] 。
- (2, 2) 是一组非互质数,且 LCM(2, 2) = 2 。得到 nums = [2,1,1,3] 。
现在,nums 中不存在相邻的非互质数。 
因此,修改后得到的最终数组是 [2,1,1,3] 。 
注意,存在其他方法可以获得相同的最终数组。

提示:

  • 1 <= nums.length <= 10^
  • 1 <= nums[i] <= 10^5
  • 生成的测试用例可以保证最终数组中的值 小于或者等于10^8

思路:

直接用栈模拟题目的操作步骤。

注意gcd函数即可

class Solution {
    public List<Integer> replaceNonCoprimes(int[] nums) {
        Stack<Integer> stack = new Stack<>();
        for (int num : nums) {
            int cur = num;
            while (!stack.isEmpty()) {
                int p = stack.peek();
                long x = gcd(cur, p);
                // 非互质
                if (x > 1) {
                    stack.pop();
                    cur = (int) (p / x * cur);
                } else {
                    break;
                }
            }
            stack.push(cur);
        }
        List<Integer> res = new ArrayList<>();
        for (int num : stack) {
            res.add(num);
        }
        return res;
    }
    public long gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
}


相关文章
|
6月前
|
Go
golang力扣leetcode 第 291 场周赛
golang力扣leetcode 第 291 场周赛
61 0
|
6月前
|
Go vr&ar
golang力扣leetcode 第 288 场周赛
golang力扣leetcode 第 288 场周赛
52 0
|
6月前
|
Go
golang力扣leetcode 第 286 场周赛
golang力扣leetcode 第 286 场周赛
58 0
|
算法 Android开发
LeetCode 周赛上分之旅 #48 一道简单的树上动态规划问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
65 1
|
6月前
|
Go
golang力扣leetcode第 294 场周赛
golang力扣leetcode第 294 场周赛
54 0
|
6月前
|
算法 Java Go
golang力扣leetcode 第 293 场周赛
golang力扣leetcode 第 293 场周赛
82 0
|
6月前
|
Go
golang力扣leetcode 第 290 场周赛
golang力扣leetcode 第 290 场周赛
52 0
|
6月前
|
Go C++
golang力扣leetcode 第 284 场周赛
golang力扣leetcode 第 284 场周赛
58 0
|
6月前
|
Go
golang力扣leetcode 第 292 场周赛
golang力扣leetcode 第 292 场周赛
66 0
|
6月前
|
存储
Leetcode第383场周赛
在LeetCode第383场周赛中,选手完成了3道题目。第一题是关于边界上的蚂蚁,蚂蚁根据非零整数数组nums的值移动,返回蚂蚁返回边界上的次数。解题方法是计算数组累加和为0的次数。第二题涉及计算网格的区域平均强度,给定一个灰度图像和阈值,返回每个像素所属区域的平均强度。解题关键在于理解相邻像素和区域定义,并计算平均强度。第三题是恢复单词初始状态的最短时间问题,通过移除前k个字符并添加k个字符,求恢复原词所需的最短时间。解题策略是检查去除前k个字符后的子串是否能作为原词的前缀。
34 1
Leetcode第383场周赛