diff --git "a/Index/\346\250\241\346\213\237.md" "b/Index/\346\250\241\346\213\237.md" index 78f6f930..d6cdd56e 100644 --- "a/Index/\346\250\241\346\213\237.md" +++ "b/Index/\346\250\241\346\213\237.md" @@ -116,6 +116,7 @@ | [1614. 括号的最大嵌套深度](https://leetcode-cn.com/problems/maximum-nesting-depth-of-the-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-nesting-depth-of-the-parentheses/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-pf5d/) | 简单 | 🤩🤩🤩🤩🤩 | | [1629. 按键持续时间最长的键](https://leetcode-cn.com/problems/slowest-key/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/slowest-key/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-zjwb/) | 简单 | 🤩🤩🤩🤩🤩 | | [1646. 获取生成数组中的最大值](https://leetcode-cn.com/problems/get-maximum-in-generated-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/get-maximum-in-generated-array/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-sj53/) | 简单 | 🤩🤩🤩🤩 | +| [1672. 最富有客户的资产总量](https://leetcode-cn.com/problems/richest-customer-wealth/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/richest-customer-wealth/solution/by-ac_oier-ai19/) | 简单 | 🤩🤩🤩🤩 | | [1688. 比赛中的配对次数](https://leetcode-cn.com/problems/count-of-matches-in-tournament/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-of-matches-in-tournament/solution/gong-shui-san-xie-jian-dan-nao-jin-ji-zh-cx7a/) | 简单 | 🤩🤩🤩🤩🤩 | | [1706. 球会落何处](https://leetcode-cn.com/problems/where-will-the-ball-fall/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/where-will-the-ball-fall/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-jz6f/) | 中等 | 🤩🤩🤩🤩 | | [1716. 计算力扣银行的钱](https://leetcode-cn.com/problems/calculate-money-in-leetcode-bank/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/calculate-money-in-leetcode-bank/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-ifit/) | 简单 | 🤩🤩🤩🤩 | @@ -139,5 +140,6 @@ | [2038. 如果相邻两个颜色均相同则删除当前颜色](https://leetcode-cn.com/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color/solution/gong-shui-san-xie-nao-jin-ji-zhuan-wan-y-a8xm/) | 中等 | 🤩🤩 | | [2043. 简易银行系统](https://leetcode-cn.com/problems/simple-bank-system/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/simple-bank-system/solution/by-ac_oier-9pqi/) | 中等 | 🤩🤩🤩🤩 | | [2047. 句子中的有效单词数](https://leetcode-cn.com/problems/number-of-valid-words-in-a-sentence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-valid-words-in-a-sentence/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-m-5pcz/) | 简单 | 🤩🤩🤩🤩 | +| [2069. 模拟行走机器人 II](https://leetcode-cn.com/problems/walking-robot-simulation-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/walking-robot-simulation-ii/solution/by-ac_oier-6zib/) | 中等 | 🤩🤩🤩🤩 | | [面试题 10.02. 变位词组](https://leetcode-cn.com/problems/group-anagrams-lcci/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/group-anagrams-lcci/solution/gong-shui-san-xie-tong-ji-bian-wei-ci-de-0iqe/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/Index/\350\204\221\347\255\213\346\200\245\350\275\254\345\274\257.md" "b/Index/\350\204\221\347\255\213\346\200\245\350\275\254\345\274\257.md" index ed63e4fc..45309b77 100644 --- "a/Index/\350\204\221\347\255\213\346\200\245\350\275\254\345\274\257.md" +++ "b/Index/\350\204\221\347\255\213\346\200\245\350\275\254\345\274\257.md" @@ -4,4 +4,5 @@ | [419. 甲板上的战舰](https://leetcode-cn.com/problems/battleships-in-a-board/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/battleships-in-a-board/solution/gong-shui-san-xie-ji-chong-sao-miao-xian-trmc/) | 中等 | 🤩🤩🤩🤩 | | [423. 从英文中重建数字](https://leetcode-cn.com/problems/reconstruct-original-digits-from-english/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reconstruct-original-digits-from-english/solution/gong-shui-san-xie-nao-jin-ji-zhuan-wan-m-vg7a/) | 中等 | 🤩🤩🤩🤩 | | [2038. 如果相邻两个颜色均相同则删除当前颜色](https://leetcode-cn.com/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color/solution/gong-shui-san-xie-nao-jin-ji-zhuan-wan-y-a8xm/) | 中等 | 🤩🤩🤩🤩🤩 | +| [2069. 模拟行走机器人 II](https://leetcode-cn.com/problems/walking-robot-simulation-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/walking-robot-simulation-ii/solution/by-ac_oier-6zib/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/LeetCode/1671-1680/1672. \346\234\200\345\257\214\346\234\211\345\256\242\346\210\267\347\232\204\350\265\204\344\272\247\346\200\273\351\207\217\357\274\210\347\256\200\345\215\225\357\274\211.md" "b/LeetCode/1671-1680/1672. \346\234\200\345\257\214\346\234\211\345\256\242\346\210\267\347\232\204\350\265\204\344\272\247\346\200\273\351\207\217\357\274\210\347\256\200\345\215\225\357\274\211.md" new file mode 100644 index 00000000..d6bdac54 --- /dev/null +++ "b/LeetCode/1671-1680/1672. \346\234\200\345\257\214\346\234\211\345\256\242\346\210\267\347\232\204\350\265\204\344\272\247\346\200\273\351\207\217\357\274\210\347\256\200\345\215\225\357\274\211.md" @@ -0,0 +1,82 @@ +### 题目描述 + +这是 LeetCode 上的 **[1672. 最富有客户的资产总量](https://leetcode-cn.com/problems/richest-customer-wealth/solution/by-ac_oier-ai19/)** ,难度为 **简单**。 + +Tag : 「模拟」 + + + +给你一个 $m * n$ 的整数网格 `accounts`,其中 $accounts[i][j]$ 是第 $i$ 位客户在第 $j$ 家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。 + +客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。 + +示例 1: +``` +输入:accounts = [[1,2,3],[3,2,1]] + +输出:6 + +解释: +第 1 位客户的资产总量 = 1 + 2 + 3 = 6 +第 2 位客户的资产总量 = 3 + 2 + 1 = 6 +两位客户都是最富有的,资产总量都是 6 ,所以返回 6 。 +``` +示例 2: +``` +输入:accounts = [[1,5],[7,3],[3,5]] + +输出:10 + +解释: +第 1 位客户的资产总量 = 6 +第 2 位客户的资产总量 = 10 +第 3 位客户的资产总量 = 8 +第 2 位客户是最富有的,资产总量是 10 +``` +示例 3: +``` +输入:accounts = [[2,8,7],[7,1,3],[1,9,5]] + +输出:17 +``` + +提示: +* $m == accounts.length$ +* $n == accounts[i].length$ +* $1 <= m, n <= 50$ +* $1 <= accounts[i][j] <= 100$ + +--- + +### 模拟 + +根据题意进行模拟即可。 + +```Java +class Solution { + public int maximumWealth(int[][] accounts) { + int m = accounts.length, n = accounts[0].length, ans = 0; + for (int i = 0; i < m; i++) { + int cur = 0; + for (int j = 0; j < n; j++) cur += accounts[i][j]; + ans = Math.max(ans, cur); + } + return ans; + } +} +``` +* 时间复杂度:$O(m * n)$ +* 空间复杂度:$O(1)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.1672` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 + diff --git "a/LeetCode/2061-2070/2069. \346\250\241\346\213\237\350\241\214\350\265\260\346\234\272\345\231\250\344\272\272 II\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/2061-2070/2069. \346\250\241\346\213\237\350\241\214\350\265\260\346\234\272\345\231\250\344\272\272 II\357\274\210\344\270\255\347\255\211\357\274\211.md" new file mode 100644 index 00000000..9c3e9db6 --- /dev/null +++ "b/LeetCode/2061-2070/2069. \346\250\241\346\213\237\350\241\214\350\265\260\346\234\272\345\231\250\344\272\272 II\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -0,0 +1,125 @@ +### 题目描述 + +这是 LeetCode 上的 **[2069. 模拟行走机器人 II](https://leetcode-cn.com/problems/walking-robot-simulation-ii/solution/by-ac_oier-6zib/)** ,难度为 **中等**。 + +Tag : 「模拟」、「脑筋急转弯」 + + + +给你一个在 `XY` 平面上的 `width x height` 的网格图,左下角 的格子为 $(0, 0)$,右上角的格子为 $(width - 1, height - 1)$ 。网格图中相邻格子为四个基本方向之一(`"North"`,`"East"`,`"South"` 和 `"West"`)。一个机器人初始在格子 $(0, 0)$ ,方向为 `"East"`。 + +机器人可以根据指令移动指定的步数。每一步,它可以执行以下操作。 + +1. 沿着当前方向尝试往前一步 。 +2. 如果机器人下一步将到达的格子超出了边界,机器人会逆时针转 90 度,然后再尝试往前一步。 + +如果机器人完成了指令要求的移动步数,它将停止移动并等待下一个指令。 + +请你实现 `Robot` 类: +* `Robot(int width, int height)` 初始化一个 `width x height` 的网格图,机器人初始在 $(0, 0)$,方向朝 `"East"`。 +* `void move(int num)` 给机器人下达前进 `num` 步的指令。 +* `int[] getPos()` 返回机器人当前所处的格子位置,用一个长度为 $2$ 的数组 $[x, y]$ 表示。 +* `String getDir()` 返回当前机器人的朝向,为 `"North"`,`"East"`,`"South"` 或者 `"West"`。 + +示例 1: +![](https://assets.leetcode.com/uploads/2021/10/09/example-1.png) +``` +输入: +["Robot", "move", "move", "getPos", "getDir", "move", "move", "move", "getPos", "getDir"] +[[6, 3], [2], [2], [], [], [2], [1], [4], [], []] + +输出: +[null, null, null, [4, 0], "East", null, null, null, [1, 2], "West"] + +解释: +Robot robot = new Robot(6, 3); // 初始化网格图,机器人在 (0, 0) ,朝东。 +robot.move(2); // 机器人朝东移动 2 步,到达 (2, 0) ,并朝东。 +robot.move(2); // 机器人朝东移动 2 步,到达 (4, 0) ,并朝东。 +robot.getPos(); // 返回 [4, 0] +robot.getDir(); // 返回 "East" +robot.move(2); // 朝东移动 1 步到达 (5, 0) ,并朝东。 + // 下一步继续往东移动将出界,所以逆时针转变方向朝北。 + // 然后,往北移动 1 步到达 (5, 1) ,并朝北。 +robot.move(1); // 朝北移动 1 步到达 (5, 2) ,并朝 北 (不是朝西)。 +robot.move(4); // 下一步继续往北移动将出界,所以逆时针转变方向朝西。 + // 然后,移动 4 步到 (1, 2) ,并朝西。 +robot.getPos(); // 返回 [1, 2] +robot.getDir(); // 返回 "West" +``` + +提示: +* $2 <= width, height <= 100$ +* $1 <= num <= 10^5$ +* `move`,`getPos` 和 `getDir` 总共调用次数不超过 $10^4$ 次。 + +--- + +### 模拟 + +根据题目给定的移动规则可知,机器人总是在外圈移动(共上下左右四条),而移动方向分为四类: + +![image.png](https://pic.leetcode-cn.com/1649906046-cdlyAL-image.png) + +当行走步数为 $mod = 2 * (w - 1) + 2 * (h - 1)$ 的整数倍时,会回到起始位置,因此我们可以通过维护一个变量 `loc` 来记录行走的总步数,并且每次将 `loc` 对 `mod` 进行取模来得到有效步数。 + +在回答 `getPos` 和 `getDir` 询问时,根据当前 `loc` 进行分情况讨论(见注释)。 + +另外还有一个小细节:根据题意,如果当前处于 $(0, 0)$ 位置,并且没有移动过,方向为 `East`,若移动过,方向则为 `South`,这可以通过一个变量 `moved` 来进行特判处理。 + +代码: +```Java +class Robot { + String[] ss = new String[]{"East", "North", "West", "South"}; + int w, h, loc; // loc: 有效(取模后)移动步数 + boolean moved; // 记录是否经过移动,用于特判 (0,0) 的方向 + public Robot(int width, int height) { + w = width; h = height; + } + public void step(int num) { + moved = true; + loc += num; + loc %= 2 * (w - 1) + 2 * (h - 1); + } + public int[] getPos() { + int[] info = move(); + return new int[]{info[0], info[1]}; + } + public String getDir() { + int[] info = move(); + int x = info[0], y = info[1], dir = info[2]; + // 特殊处理当前在 (0,0) 的情况,当未移动过方向为 East,移动过方向为 South + if (x == 0 && y == 0) return moved ? ss[3] : ss[0]; + return ss[dir]; + } + int[] move() { + if (loc <= w - 1) { + // 当移动步数范围在 [0,w-1] 时,所在位置为外圈的下方,方向为 East + return new int[]{loc, 0, 0}; + } else if (loc <= (w - 1) + (h - 1)) { + // 当移动步数范围在 [w,(w-1)+(h-1)] 时,所在位置为外圈的右方,方向为 North + return new int[]{w - 1, loc - (w - 1), 1}; + } else if (loc <= 2 * (w - 1) + (h - 1)) { + // 当移动步数范围在 [(w-1)+(h-1)+1,2*(w-1)+(h-1)] 时,所在位置为外圈的上方,方向为 West + return new int[]{(w - 1) - (loc - ((w - 1) + (h - 1))), h - 1, 2}; + } else { + // 当移动步数范围在 [2*(w-1)+(h-1)+1,2*(w-1)+2*(h-1)] 时,所在位置为外圈的左方,方向为 South + return new int[]{0, (h - 1) - (loc - (2 * (w - 1) + (h - 1))), 3}; + } + } +} +``` +* 时间复杂度:$O(1)$ +* 空间复杂度:$O(1)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.2169` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 + diff --git "a/LeetCode/901-910/902. \346\234\200\345\244\247\344\270\272 N \347\232\204\346\225\260\345\255\227\347\273\204\345\220\210\357\274\210\345\233\260\351\232\276\357\274\211.md" "b/LeetCode/901-910/902. \346\234\200\345\244\247\344\270\272 N \347\232\204\346\225\260\345\255\227\347\273\204\345\220\210\357\274\210\345\233\260\351\232\276\357\274\211.md" index af02b545..3bb1edba 100644 --- "a/LeetCode/901-910/902. \346\234\200\345\244\247\344\270\272 N \347\232\204\346\225\260\345\255\227\347\273\204\345\220\210\357\274\210\345\233\260\351\232\276\357\274\211.md" +++ "b/LeetCode/901-910/902. \346\234\200\345\244\247\344\270\272 N \347\232\204\346\225\260\345\255\227\347\273\204\345\220\210\357\274\210\345\233\260\351\232\276\357\274\211.md" @@ -129,6 +129,16 @@ class Solution { --- +### 总结 + +数位 DP 的难度取决于「限制条件」的多少,而 LC 上仅有的几道数位 DP 题目限制条件都很少,且不需要引入额外的数据结构来记录状态,因此都属于数位 DP 的入门难度(LC 难度均为 Hard)。 + +几乎所有的数位 DP 问题都可以归纳到上述的解法 :「将问题抽象为求解一个 $[0, x]$ / $[1, x]$ 范围方案数的方法」->「对方案数统计根据 位数 来分情况讨论:数位相等的情况 + 数位不等情况」->「统计数位相等的方案数时,需要按位处理,并根据限制条件做逻辑;统计数位不等的方案数时,通常要做一些预处理,然后配合乘法原理直接算得」。 + +在还没卷到数位 DP 烂大街的现在,掌握此类求解方式单一,普遍定位为「困难」的数位 DP 类型,还是极具性价比的。 + +--- + ### 最后 这是我们「刷穿 LeetCode」系列文章的第 `No.902` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。