├── .gitignore ├── README.md ├── SUMMARY.md ├── book.json ├── 第一遍 ├── 12. Integer to Roman.md ├── 13. Roman to Integer.md ├── 169. Majority Element.md ├── 206. Reverse Linked List.md ├── 217. Contains Duplicate.md ├── 268. Missing Number.md ├── 343. Integer Break.md ├── 350. Intersection of Two Arrays II.md ├── 378. Kth Smallest Element in a Sorted Matrix.md ├── 392. Is Subsequence.md ├── 401. Binary Watch.md ├── 409. Longest Palindrome.md ├── 427. Construct Quad Tree.md ├── 429. N-ary Tree Level Order Traversal.md ├── 447. Number of Boomerangs.md ├── 485. Max Consecutive Ones.md ├── 486. Predict the Winner.md ├── 492. Construct the Rectangle.md ├── 496. Next Greater Element I.md ├── 508. Most Frequent Subtree Sum.md ├── 509. Fibonacci Number.md ├── 513. Find Bottom Left Tree Value.md ├── 515. Find Largest Value in Each Tree Row.md ├── 526. Beautiful Arrangement.md ├── 535. Encode and Decode TinyURL.md ├── 540. Single Element in a Sorted Array.md ├── 559. Maximum Depth of N-ary Tree.md ├── 561. Array Partition I.md ├── 566. Reshape the Matrix.md ├── 575. Distribute Candies.md ├── 589. N-ary Tree Preorder Traversal.md ├── 590. N-ary Tree Postorder Traversal.md ├── 609. Find Duplicate File in System.md ├── 617. Merge Two Binary Trees.md ├── 637. Average of Levels in Binary Tree.md ├── 647. Palindromic Substrings.md ├── 654. Maximum Binary Tree.md ├── 669. Trim a Binary Search Tree.md ├── 682. Baseball Game.md ├── 693. Binary Number with Alternating Bits.md ├── 695. Max Area of Island.md ├── 700. Search in a Binary Search Tree.md ├── 701. Insert into a Binary Search Tree.md ├── 706. Design HashMap.md ├── 728. Self Dividing Numbers.md ├── 739. Daily Temperatures.md ├── 748. Shortest Completing Word.md ├── 762. Prime Number of Set Bits in Binary Representation.md ├── 763. Partition Labels.md ├── 766. Toeplitz Matrix.md ├── 771. Jewels and Stones.md ├── 784. Letter Case Permutation.md ├── 789. Escape The Ghosts.md ├── 791. Custom Sort String.md ├── 797. All Paths From Source to Target.md ├── 806. Number of Lines To Write String.md ├── 807. Max Increase to Keep City Skyline.md ├── 811. Subdomain Visit Count.md ├── 812. Largest Triangle Area.md ├── 814. Binary Tree Pruning.md ├── 817. Linked List Components.md ├── 821. Shortest Distance to a Character.md ├── 824. Goat Latin.md ├── 832. Flipping an Image.md ├── 841. Keys and Rooms.md ├── 852. Peak Index in a Mountain Array.md ├── 856. Score of Parentheses.md ├── 861. Score After Flipping Matrix.md ├── 865. Smallest Subtree with all the Deepest Nodes.md ├── 867. Transpose Matrix.md ├── 868. Binary Gap.md ├── 872. Leaf-Similar Trees.md ├── 876. Middle of the Linked List.md ├── 877. Stone Game.md ├── 883. Projection Area of 3D Shapes.md ├── 884. Uncommon Words from Two Sentences.md ├── 885. Spiral Matrix III.md ├── 888. Fair Candy Swap.md ├── 889. Construct Binary Tree from Preorder and Postorder Traversal.md ├── 890. Find and Replace Pattern.md ├── 892. Surface Area of 3D Shapes.md ├── 893. Groups of Special-Equivalent Strings.md ├── 894. All Possible Full Binary Trees.md ├── 896. Monotonic Array.md ├── 897. Increasing Order Search Tree.md ├── 905. Sort Array By Parity.md ├── 908. Smallest Range I.md ├── 917. Reverse Only Letters.md ├── 921. Minimum Add to Make Parentheses Valid.md ├── 922. Sort Array By Parity II.md ├── 929. Unique Email Addresses.md ├── 933. Number of Recent Calls.md ├── 937. Reorder Log Files.md ├── 938. Range Sum of BST.md ├── 94. Binary Tree Inorder Traversal.md ├── 942. DI String Match.md ├── 944. Delete Columns to Make Sorted.md ├── 946. Validate Stack Sequences.md ├── 947. Most Stones Removed with Same Row or Column.md ├── 950. Reveal Cards In Increasing Order.md ├── 951. Flip Equivalent Binary Trees.md ├── 953. Verifying an Alien Dictionary.md ├── 959. Regions Cut By Slashes.md ├── 961. N-Repeated Element in Size 2N Array.md ├── 965. Univalued Binary Tree.md ├── 969. Pancake Sorting.md ├── 973. K Closest Points to Origin.md ├── 976. Largest Perimeter Triangle.md ├── 977. Squares of a Sorted Array.md ├── 979. Distribute Coins in Binary Tree.md ├── 980. Unique Paths III.md ├── 983. Minimum Cost For Tickets.md ├── 993. Cousins in Binary Tree.md └── README.md └── 第二遍 ├── 801. Minimum Swaps To Make Sequences Increasing.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## leetcode 讲解 2 | 3 | leetcode 是一个 Online Judge 网站,在线练习编程,尤其是练习数据结构和算法相关的题。 4 | 5 | 刷 OJ 对于锻炼自己的 **编程思维** 是非常有帮助的。 6 | 7 | 这份 gitbook 电子书,是我刷 leetcode 过程中的一些总结,所使用的编程语言是 typescript 和 javascript。 8 | 9 | **几点小建议**: 10 | 11 | 1. 按照 AC(accepted)率从高到低刷题,这样就会从易到难,提供一个进步的缓冲空间,不至于一上来就被打击到。 12 | 2. 按照算法和数据结构体系,逐个模块的掌握,leetcode 会提示哪些题目是类似的,另外网上也有不少按算法和数据结构总结的解答电子书可以参照。 13 | 3. 做不出来的时候可以看 leetcode 网站上的 Discuss 和 Solutions ,有不少大神的解题方法和精简代码。当然也可以在互联网上搜索,有很多讲解 leetcode 的博客。 14 | 4. 学而不思则罔,思而不学则殆。直接看别人的答案没有自己的思考过程是不行的,比较难的题目自己一个劲的思考不学习别人的先进方法也是不行的。 15 | 16 | **本教程的核心目的**:做个总结,按照算法体系把有价值的题归纳总结、举一反三,得出一些有价值的思考和结论。 17 | 18 | 本 gitbook 的 github 仓库:[leetcode 讲解](https://github.com/liuqinh2s/leetcode) 19 | 20 | 本 gitbook 的地址:[leetcode 讲解](https://liuqinh2s.gitbooks.io/leetcode/) 21 | 22 | 关于作者: 23 | 24 | - [liuqinh2s 的个人主页](https://liuqinh2s.github.io/blog/about) 25 | 26 | 参考\(实际上参考了很多网络上的资料,如果您觉得其中有您的工作成果,请私信我并指明出处\) 27 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "liuqinh2s ", 3 | "description": "This is leetcode solutions.", 4 | "extension": null, 5 | "generator": "site", 6 | "isbn": "", 7 | "links": { 8 | "sharing": { 9 | "all": null, 10 | "facebook": null, 11 | "google": null, 12 | "twitter": null, 13 | "weibo": null 14 | }, 15 | "sidebar": { 16 | "About me": "https://liuqinh2s.github.io/blog/about", 17 | "Liuqinh2s' Homepage": "https://liuqinh2s.github.io/blog" 18 | } 19 | }, 20 | "output": null, 21 | "pdf": { 22 | "fontSize": 12, 23 | "footerTemplate": null, 24 | "headerTemplate": null, 25 | "margin": { 26 | "bottom": 36, 27 | "left": 62, 28 | "right": 62, 29 | "top": 36 30 | }, 31 | "pageNumbers": false, 32 | "paperSize": "a4" 33 | }, 34 | "plugins": [ 35 | "disqus", 36 | "github", 37 | "expandable-chapters-small", 38 | "katex", 39 | "anchors", 40 | "sitemap" 41 | ], 42 | "pluginsConfig": { 43 | "disqus": { 44 | "shortName": "liuqinh2s-leetcode" 45 | }, 46 | "github": { 47 | "url": "https://github.com/liuqinh2s/leetcode" 48 | }, 49 | "sitemap": { 50 | "hostname": "https://liuqinh2s.gitbooks.io/leetcode/" 51 | } 52 | }, 53 | "title": "leetcode讲解", 54 | "variables": {} 55 | } 56 | -------------------------------------------------------------------------------- /第一遍/12. Integer to Roman.md: -------------------------------------------------------------------------------- 1 | ### [12. Integer to Roman](https://leetcode.com/problems/integer-to-roman/) 2 | 3 | Given an integer, convert it to a roman numeral. 4 | 5 | Input is guaranteed to be within the range from 1 to 3999. 6 | 7 | #### 翻译 8 | 9 | 给定一个整数,把它转化成罗马数字形式。 10 | 11 | 输入确保在 1 到 3999 的范围内。 12 | 13 | #### 分析 14 | 15 | 首先要了解罗马数字的构成规则: 16 | 17 | 基本符号: 18 | 19 | - I: 1 20 | - V: 5 21 | - X: 10 22 | - L: 50 23 | - C: 100 24 | - D: 500 25 | - M: 1000 26 | 27 | 字母可以重复,但不超过三次(左减右加): 28 | 29 | - VI : 6 30 | - IV : 4 31 | - VII : 7 32 | - VIII : 8 33 | - IX : 9 34 | 35 | >总结罗马数字的规则: 36 | 罗马数是逢5进位的符号体系,右边最多加三个,到第四个的时候就要放到左边变成减法表示。 37 | 38 | 罗马数字的构成其实缺了一点统一美,如果字母可以重复4次,就不用放左边这种特殊情况了。那么问题就变得及其简单,不管什么数字都是由基本符号累加得到(而没有放左边减一这种特殊情况),那么整型数到罗马数字转换的时候,使用贪心算法,每次挑选比当前数略小的最大基本符号,然后用当前数减去这个符号,依次确定最高位的符号。 39 | 40 | 算法就会是这个样: 41 | 42 | Python代码: 43 | 44 | ```Python 45 | class Solution(object): 46 | def intToRoman(self, num): 47 | """ 48 | :type num: int 49 | :rtype: str 50 | """ 51 | values = [1000,500,100,50,10,5,1] 52 | strings = ["M","D","C","L","X","V","I"] 53 | ans = "" 54 | for i in range(len(values)): 55 | while num>=values[i]: 56 | num -= values[i] 57 | ans += strings[i] 58 | return ans 59 | ``` 60 | 61 | 如果我们把放左边这种符号抽象的**看成一个组合符号**,问题就变得简单了,每次右边加三之后要出现一个左边减一: 62 | 63 | - IV : 4 64 | - IX : 9 65 | - XL : 40 66 | - XC : 90 67 | - CD : 400 68 | - CM : 900 69 | 70 | 以上就是所有应该特殊处理的组合符号了。 71 | 72 | #### 代码 73 | 74 | Python代码: 75 | 76 | ```Python 77 | class Solution(object): 78 | def intToRoman(self, num): 79 | """ 80 | :type num: int 81 | :rtype: str 82 | """ 83 | values = [1000,900,500,400,100,90,50,40,10,9,5,4,1] 84 | strings = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"] 85 | ans = "" 86 | for i in range(len(values)): 87 | while num>=values[i]: 88 | num -= values[i] 89 | ans += strings[i] 90 | return ans 91 | ``` 92 | 93 | C++代码: 94 | 95 | ```C++ 96 | class Solution { 97 | public: 98 | string intToRoman(int num) { 99 | vector strings = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; 100 | int val[] = {1000,900,500,400,100,90,50,40,10,9,5,4,1}; 101 | string ans=""; 102 | for(int i=0; i=val[i]) { 104 | num -= val[i]; 105 | ans += strings[i]; 106 | } 107 | } 108 | return ans; 109 | } 110 | }; 111 | ``` 112 | 113 | Java代码: 114 | 115 | ```Java 116 | public class Solution { 117 | public String intToRoman(int num) { 118 | String[] s = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; 119 | int[] v = {1000,900,500,400,100,90,50,40,10,9,5,4,1}; 120 | String ans = ""; 121 | for(int i=0;i=v[i]){ 123 | num -= v[i]; 124 | ans += s[i]; 125 | } 126 | } 127 | return ans; 128 | } 129 | } 130 | ``` 131 | 132 | 从这道题中我们要学会的思想就是: 133 | 134 | 1. 尽量让规则变得统一而简单起来,去掉一些多余的特殊情况,代码即逻辑,规则简单代码就简单。 135 | 2. 碰到特殊的规则,我们可以尝试不用构造新的代码逻辑去处理它,而使用直接存储特殊例子来把它归纳进原有的规则里。 136 | 137 | 相关题目:[## 13. Roman to Integer](https://liuqinh2s.gitbooks.io/leetcode/%E7%AC%AC%E4%B8%80%E9%81%8D/13.%20Roman%20to%20Integer.html) -------------------------------------------------------------------------------- /第一遍/13. Roman to Integer.md: -------------------------------------------------------------------------------- 1 | ## 13. Roman to Integer 2 | 3 | [题目地址](https://leetcode.com/problems/roman-to-integer/) 4 | 5 | Given a roman numeral, convert it to an integer. 6 | 7 | Input is guaranteed to be within the range from 1 to 3999. 8 | 9 | ### 翻译 10 | 11 | 给定一个罗马数,把它转化成整数。 12 | 13 | 输入保证在1到3999的范围内。 14 | 15 | ### 分析 16 | 17 | 罗马数字有:{'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000},(这里是用键值对表示) 18 | 19 | 罗马数字的组合规则:左边是减,右边是加。如:IV=4,VI=6。 20 | 21 | 那么我们很容易想到,先统一加起来,然后看到相邻的逆序(小的在左,大的在右,为逆序),就减2倍这个数(因为原来多加了一次,所以减2倍)。 22 | 23 | 代码: 24 | 25 | ```Python 26 | class Solution(object): 27 | def romanToInt(self, s): 28 | """ 29 | :type s: str 30 | :rtype: int 31 | """ 32 | map={'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000} 33 | sum=0 34 | for i in range(len(s)): 35 | sum += map[s[i]] 36 | if i>0 and map[s[i-1]]& nums) { 11 | unordered_map hash; 12 | for(auto i:nums){ 13 | hash[i]++; 14 | } 15 | for(auto i:hash){ 16 | if(i.second>=2) 17 | return true; 18 | } 19 | return false; 20 | } 21 | }; 22 | ``` 23 | -------------------------------------------------------------------------------- /第一遍/268. Missing Number.md: -------------------------------------------------------------------------------- 1 | ## 268. Missing Number 2 | 3 | [题目地址](https://leetcode.com/problems/missing-number/) 4 | 5 | Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. 6 | 7 | For example, 8 | Given nums = [0, 1, 3] return 2. 9 | 10 | Note: 11 | Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? 12 | 13 | ### 翻译 14 | 15 | 给定一个数组包含 0, 1, 2, ..., n, n个不相同的数字,从数组中找出这个缺失的数。 16 | 17 | 例如, 18 | 19 | 给定 nums = [0, 1, 3] 返回 2。 20 | 21 | 注意: 22 | 23 | 你的算法应该运行在线性的时间复杂度内。你能只使用常数空间复杂度来实现它吗? 24 | 25 | ### 分析 26 | 27 | 这题极其简单啊,用加减法就能找出那个数啊。 28 | 29 | 代码: 30 | 31 | ```Python 32 | class Solution(object): 33 | def missingNumber(self, nums): 34 | """ 35 | :type nums: List[int] 36 | :rtype: int 37 | """ 38 | count1=0 39 | count2=0 40 | for i in range(len(nums)+1): 41 | count1 += i 42 | for i in nums: 43 | count2 += i 44 | return count1-count2 45 | ``` 46 | -------------------------------------------------------------------------------- /第一遍/343. Integer Break.md: -------------------------------------------------------------------------------- 1 | ### 343. Integer Break 2 | 3 | [题目地址](https://leetcode.com/problems/integer-break/) 4 | 5 | 好吧我还是把题目贴出来,反正不长: 6 | 7 | Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get. 8 | 9 | For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4). 10 | 11 | Note: You may assume that n is not less than 2 and not larger than 58. 12 | 13 | 又是一个要 **靠罗列来发现规律** 的例子: 14 | 15 | 规模n|最大值 16 | ----|---- 17 | 2 | `1*1` 18 | 3 | `2*1` 19 | 4 | `2*2` 20 | 5 | `3*2` 21 | 6 | `3*3` 22 | 7 | `3*2*2` 23 | 8 | `3*3*2` 24 | 9 | `3*3*3` 25 | 10 | `3*3*2*2` 26 | 11 | `3*3*3*2` 27 | 12 | `3*3*3*3` 28 | 29 | >好,我们定义一个最大值数组`dp[n]`(dynamic programming),`dp[5]`即规模为5时候的最大值。 30 | 31 | 从上面的表中,你发现了什么规律? 32 | 33 | 1. 尽可能避免拆成1 34 | 2. 规模为4的时候,恰好`dp[4]=4`,之后`dp[5]`就开始>5了,而之前的`dp[2]、dp[3]`都是小于自身规模(n=2,n=3)的。 35 | 3. 如果我们把2到6看成基本集合,那么后面从7开始是可以归因到2到6的,首先归因到6肯定不对,我们不欢迎1的拆分除非迫不得已(2和3只能那样拆才能拆成2个数的乘积啊),比如7可以写成`2*dp[5]=2*3*2`,也可以写成`3*dp[4]=3*2*2`,但是没必要写成`4*dp[3]`了,因为`dp[3]`已经小于3了,也就是说,我们每次归因都到`dp[4]`打止。但这还是不对,我们看9,9可以归因为`2*dp[7],3*dp[6],4*dp[5],5*dp[4]`(这可不行啊,5已经小于`dp[5]`了,所以完全不能用,之后的什么6啊,7啊更加不能用,所以其实也是到4打止了,不再往前搜),所以实际上我们最多往前归因4位。其实这还是不对,聪明的你应该已经发现,往前归因4位,其实跟归因2位两次是一样的。所以我们只需从`2*dp[n-2],3*dp[n-3]`中选出大者就行。 36 | 4. 我们得到动态规划公式(**动态规划就是归因(多元因)啊,而递归则是单一因**):`dp[n]=max(2*dp[n-2],3*dp[n-3])`,且n>=7(因为我们不越过`dp[4]`啊)。 37 | 38 | 代码如下: 39 | 40 | ```Python 41 | class Solution(object): 42 | def integerBreak(self, n): 43 | """ 44 | :type n: int 45 | :rtype: int 46 | """ 47 | dp = [0]*(n+7) 48 | dp[2]=1 49 | dp[3]=2 50 | dp[4]=4 51 | dp[5]=6 52 | dp[6]=9 53 | if(n>=7): 54 | for x in range(7, n + 1): 55 | dp[x] = max(3 * dp[x - 3], 2 * dp[x - 2]) 56 | return dp[n] 57 | ``` 58 | 59 | 我自己感到这代码有着深深的蛋疼(手动赋了一大堆值),因为我看到别人是这样写的: 60 | 61 | ```Python 62 | class Solution(object): 63 | def integerBreak(self, n): 64 | """ 65 | :type n: int 66 | :rtype: int 67 | """ 68 | if n<4: 69 | return n-1 70 | dp = [0]*(n+1) 71 | dp[2], dp[3] = 2, 3 72 | for x in range(4, n + 1): 73 | dp[x] = max(3 * dp[x - 3], 2 * dp[x - 2]) 74 | return dp[n] 75 | ``` 76 | 77 | 好吧,他的代码其实也差不多。 78 | 79 | 下面真正吊炸天的来了。 80 | 81 | 聪明的你肯定已经发现,这完全就是个2跟3的游戏,是的,事实就是如此。 82 | 83 | - n%3==0时,就全部用3 84 | - n%3==2时,勉为其难用个2吧 85 | - n%3==1时,就再勉为其难用两个2吧 86 | 87 | 当n%3==3,哈哈别傻了, 88 | 89 | 当然你还得看到,最开始的2个里面是有1的,可不要忘了。 90 | 91 | 所以,得到牛逼的专门解题代码: 92 | 93 | ```Python 94 | class Solution(object): 95 | def integerBreak(self, n): 96 | """ 97 | :type n: int 98 | :rtype: int 99 | """ 100 | if n < 4: 101 | return n - 1 102 | if n % 3 == 0: 103 | return 3 ** (n / 3) 104 | if n % 3 == 1: 105 | return 3 ** ((n - 3) / 3) * 4 106 | if n % 3 == 2: 107 | return 3 ** ((n - 2) / 3) * 2 108 | ``` 109 | 110 | 这种题也就娱乐娱乐,程序员还是要以工程代码为主业啊。 111 | -------------------------------------------------------------------------------- /第一遍/350. Intersection of Two Arrays II.md: -------------------------------------------------------------------------------- 1 | ### 350. Intersection of Two Arrays II 2 | 3 | [题目地址](https://leetcode.com/problems/intersection-of-two-arrays-ii/) 4 | 5 | Given two arrays, write a function to compute their intersection. 6 | 7 | Example: 8 | Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2]. 9 | 10 | Note: 11 | Each element in the result should appear as many times as it shows in both arrays. 12 | The result can be in any order. 13 | Follow up: 14 | What if the given array is already sorted? How would you optimize your algorithm? 15 | What if nums1's size is small compared to nums2's size? Which algorithm is better? 16 | What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once? 17 | 18 | 翻译: 19 | 20 | 给两个数组,写一个函数来计算它们的交集。 21 | 22 | 例子: 23 | 24 | 给定 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2, 2]. 25 | 26 | 注意: 27 | 28 | 结果中的每个元素出现的次数都应该与它们出现在这两个数组中的次数一样多。 29 | 30 | 结果中的元素顺序随意。 31 | 32 | 接下来: 33 | 34 | 如果给的数组已经排好了序怎么办?你怎么优化你的算法? 35 | 如果 nums1 的长度比 nums2 长怎么办?哪种算法更好? 36 | 如果 nums2 的元素存储在磁盘上,并且内存有限以至于你无法一次性把所有元素都加载到内存,怎么办? 37 | 38 | 先上代码: 39 | 40 | ```Python 41 | class Solution(object): 42 | def intersect(self, nums1, nums2): 43 | """ 44 | :type nums1: List[int] 45 | :type nums2: List[int] 46 | :rtype: List[int] 47 | """ 48 | ans=[] 49 | c = collections.Counter(nums1) 50 | for x in nums2: 51 | if c[x]>0: 52 | ans += x, 53 | c[x] -= 1 54 | return ans 55 | ``` 56 | 57 | 很简单吧,遍历两个数组即可(先把其中一个用哈希表,即 hashtable 存起来,然后遍历另一个,一边遍历一边匹配,匹配到了就加进结果集,然后哈希表相应项减一)。没有任何难度。 58 | 59 | 再来看题目给出的附加问题: 60 | 61 | 跟排没排好序没有半毛钱关系,因为你至少要遍历一遍吧,O(n)的时间总是要的。 62 | 63 | nums1 和 nums2 哪个长,也没有半毛钱关系(你把长的用哈希表存起来,再去匹配短的,和把短的用哈希表存起来,再去匹配唱的,不是一样的嘛)。 64 | 65 | 如果 nums2 无法一次性拿出来,那就分几次拿呗,同样,没有半毛钱关系。 66 | 67 | 这附加问题有点古怪啊,我没看出来有什么意义啊,求看懂了的同学教教我。 68 | -------------------------------------------------------------------------------- /第一遍/378. Kth Smallest Element in a Sorted Matrix.md: -------------------------------------------------------------------------------- 1 | ### 378. Kth Smallest Element in a Sorted Matrix 2 | 3 | Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix. 4 | 5 | Note that it is the kth smallest element in the sorted order, not the kth distinct element. 6 | 7 | Example: 8 | 9 | ``` 10 | matrix = [ 11 | [ 1, 5, 9], 12 | [10, 11, 13], 13 | [12, 13, 15] 14 | ], 15 | k = 8, 16 | 17 | return 13. 18 | ``` 19 | 20 | Note: 21 | 22 | You may assume k is always valid, 1 ≤ k ≤ n^2. 23 | 24 | #### 翻译 25 | 26 | 给定一个 n x n 的矩阵,它的行和列都是按升序排列的,找到矩阵中第k小的元素。 27 | 28 | 注意:是按排序第k小的元素,不是第k个不同的元素。 29 | 30 | 例子: 31 | 32 | ``` 33 | matrix = [ 34 | [ 1, 5, 9], 35 | [10, 11, 13], 36 | [12, 13, 15] 37 | ], 38 | k = 8, 39 | 40 | return 13. 41 | ``` 42 | 43 | 注意: 44 | 45 | 你应该假设k总是有效的,1 ≤ k ≤ n^2。 46 | 47 | #### 分析 48 | 49 | 算法题嘛,让我们先从复杂度高的算法开始逐步进化到复杂度低的吧。 50 | 51 | **利用数据结构:堆** 52 | 53 | 首先我们很容易想到,可以利用小根堆来存放所有元素,然后弹出到第k个,那就是第k小的啦。遍历一遍矩阵,复杂度:O(n^2),弹出堆顶以及维护堆,k*log(n^2)。复杂度是有点高。 54 | 55 | ```Python 56 | class Solution(object): 57 | def kthSmallest(self, matrix, k): 58 | """ 59 | :type matrix: List[List[int]] 60 | :type k: int 61 | :rtype: int 62 | """ 63 | q = [] 64 | for i in range(0,len(matrix)): 65 | for j in range(0,len(matrix[0])): 66 | heapq.heappush(q,matrix[i][j]) 67 | for x in range(1,k): 68 | heapq.heappop(q) 69 | return heapq.heappop(q) 70 | # 下面的代码用了一个库函数,哈哈 71 | class Solution(object): 72 | def kthSmallest(self, matrix, k): 73 | """ 74 | :type matrix: List[List[int]] 75 | :type k: int 76 | :rtype: int 77 | """ 78 | q = [] 79 | for i in range(0,len(matrix)): 80 | for j in range(0,len(matrix[0])): 81 | heapq.heappush(q,matrix[i][j]) 82 | 83 | return heapq.nsmallest(k, q)[k-1] 84 | ``` 85 | 86 | 这里我们漏了一个条件就是:行和列都是升序排列的,所以没有必要遍历一遍整个矩阵。 87 | 88 | 算法: 89 | 90 | 首先将矩阵的左上角(下标0,0)元素加入堆 91 | 92 | 然后执行k次循环: 93 | 94 | 弹出堆顶元素top,记其下标为i, j 95 | 96 | 将其下方元素matrix[i + 1][j],与右方元素matrix[i][j + 1]加入堆(若它们没有加入过堆) 97 | 98 | 我们还是维护一个小根堆,不过这次我们一边加元素进堆(每次都找堆顶元素在矩阵中的下面和右边的元素入堆),一边弹出堆顶(弹k次即可哦)。复杂度:入堆是2log(n^2),弹出堆顶并维护堆是log(n^2),所以时间复杂度是O(log(n^2))。 99 | 100 | ```Python 101 | class Solution(object): 102 | def kthSmallest(self, matrix, k): 103 | """ 104 | :type matrix: List[List[int]] 105 | :type k: int 106 | :rtype: int 107 | """ 108 | q = [(matrix[0][0], 0, 0)] 109 | n = len(matrix) 110 | visited = [[False]*n for i in range(n)] 111 | for x in range(k): 112 | ans, i, j = heapq.heappop(q) 113 | if i= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code? 21 | 22 | [题目地址](https://leetcode.com/problems/is-subsequence/) 23 | 24 | 这题我觉得很简单啊,不知道为何评级是medium。 25 | 26 | 就是遍历两个字符串就行了。直接上代码,看不懂可以在评论里面写上,我会针对性讲解。 27 | 28 | ```C++ 29 | class Solution { 30 | public: 31 | bool isSubsequence(string s, string t) { 32 | int i=0,j=0; 33 | while(i>6, i&0x3F 74 | if h<12 and m<60: 75 | ans += '%d:%02d' %(h, m), 76 | return ans 77 | 78 | ``` 79 | 80 | #### 枚举 81 | 82 | 枚举小时和分钟(共12*60种),读取1的个数,如果和num相等就加进结果集。 83 | 84 | 代码: 85 | 86 | ```Python 87 | class Solution(object): 88 | def readBinaryWatch(self, num): 89 | """ 90 | :type num: int 91 | :rtype: List[str] 92 | """ 93 | ans = [] 94 | for h in range(12): 95 | for m in range(60): 96 | if bin(h).count('1')+bin(m).count('1')==num: 97 | ans.append("%d:%02d" %(h,m)) 98 | return ans 99 | ``` 100 | -------------------------------------------------------------------------------- /第一遍/409. Longest Palindrome.md: -------------------------------------------------------------------------------- 1 | ### 409. Longest Palindrome 2 | 3 | Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters. 4 | 5 | This is case sensitive, for example "Aa" is not considered a palindrome here. 6 | 7 | Note: 8 | Assume the length of given string will not exceed 1,010. 9 | 10 | Example: 11 | 12 | Input: 13 | "abccccdd" 14 | 15 | Output: 16 | 7 17 | 18 | Explanation: 19 | One longest palindrome that can be built is "dccaccd", whose length is 7. 20 | 21 | [题目地址](https://leetcode.com/problems/longest-palindrome/) 22 | 23 | 这题有点小儿科了,很简单,你看有多少个对子(打过牌吗,就是看有多少对子),然后看有没有一个单(注意:只需要一个单,放中间就行了)。 24 | 25 | ```C++ 26 | class Solution { 27 | public: 28 | int longestPalindrome(string s) { 29 | unordered_map hash; 30 | int count=0; 31 | int flag=0;//看有没有单 32 | for(auto i:s){ 33 | hash[i]++; 34 | } 35 | for(auto i:hash){ 36 | if(i.second%2 != 0) 37 | flag=1; 38 | count += (i.second/2)*2;//把对子全都加上 39 | } 40 | return count+flag; 41 | } 42 | }; 43 | ``` 44 | -------------------------------------------------------------------------------- /第一遍/427. Construct Quad Tree.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | We want to use quad trees to store an `N x N` boolean grid. Each cell in the grid can only be true or false. The root node represents the whole grid. For each node, it will be subdivided into four children nodes **until the values in the region it represents are all the same**. 4 | 5 | Each node has another two boolean attributes : `isLeaf` and `val`. `isLeaf` is true if and only if the node is a leaf node. The `val` attribute for a leaf node contains the value of the region it represents. 6 | 7 | Your task is to use a quad tree to represent a given grid. The following example may help you understand the problem better: 8 | 9 | Given the `8 x 8` grid below, we want to construct the corresponding quad tree: 10 | 11 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/01/962_grid.png) 12 | 13 | It can be divided according to the definition above: 14 | 15 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/01/962_grid_divided.png) 16 | 17 | The corresponding quad tree should be as following, where each node is represented as a `(isLeaf, val)` pair. 18 | 19 | For the non-leaf nodes, `val` can be arbitrary, so it is represented as `*`. 20 | 21 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/01/962_quad_tree.png) 22 | 23 | **Note:** 24 | 25 | 1. `N` is less than `1000` and guaranteened to be a power of 2. 26 | 2. If you want to know more about the quad tree, you can refer to its wiki. 27 | 28 | [题目地址](https://leetcode.com/problems/construct-quad-tree/) 29 | 30 | ## 讲解 31 | 32 | 这道题我一看就想到了递归,因为每次对更小规模的方形的处理都是一样的,调用自身就行了。唯一需要注意的点是x,y不要弄反了。x是第几列,y是第几行。 33 | 34 | ## java 35 | 36 | ```java 37 | /* 38 | // Definition for a QuadTree node. 39 | class Node { 40 | public boolean val; 41 | public boolean isLeaf; 42 | public Node topLeft; 43 | public Node topRight; 44 | public Node bottomLeft; 45 | public Node bottomRight; 46 | 47 | public Node() {} 48 | 49 | public Node(boolean _val,boolean _isLeaf,Node _topLeft,Node _topRight,Node _bottomLeft,Node _bottomRight) { 50 | val = _val; 51 | isLeaf = _isLeaf; 52 | topLeft = _topLeft; 53 | topRight = _topRight; 54 | bottomLeft = _bottomLeft; 55 | bottomRight = _bottomRight; 56 | } 57 | }; 58 | */ 59 | class Solution { 60 | public Node construct(int[][] grid) { 61 | return getNode(grid, 0, 0, grid.length); 62 | } 63 | 64 | private Node getNode(int[][] grid, int x, int y, int size){ 65 | int sum = 0; 66 | for(int i=0;i children; 37 | 38 | public Node() {} 39 | 40 | public Node(int _val,List _children) { 41 | val = _val; 42 | children = _children; 43 | } 44 | }; 45 | */ 46 | class Solution { 47 | List> result = new ArrayList>(); 48 | public List> levelOrder(Node root) { 49 | if(root==null){ 50 | return result; 51 | } 52 | Queue queue = new LinkedList<>(); 53 | queue.offer(root); 54 | int children_num = 1; 55 | List rootList = new ArrayList(); 56 | rootList.add(root.val); 57 | result.add(rootList); 58 | while(!queue.isEmpty()){ 59 | List list = new ArrayList<>(); 60 | int count=0; 61 | for(int i=0;i0){ 73 | result.add(list); 74 | } 75 | } 76 | return result; 77 | } 78 | } 79 | ``` -------------------------------------------------------------------------------- /第一遍/447. Number of Boomerangs.md: -------------------------------------------------------------------------------- 1 | ### 447. Number of Boomerangs 2 | 3 | Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters). 4 | 5 | Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive). 6 | 7 | Example: 8 | 9 | Input: 10 | 11 | [[0,0],[1,0],[2,0]] 12 | 13 | Output: 14 | 15 | 2 16 | 17 | Explanation: 18 | 19 | The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]] 20 | 21 | #### 翻译 22 | 23 | 给定 n 个两两各不相同的平面上的点,一个 “回旋镖” 是一个元组(tuple)的点(i,j,k),并且 i 和 j 的距离等于 i 和 k之间的距离(考虑顺序)。 24 | 25 | 找出回旋镖的个数。你可以假设 n 不大于500,点的坐标范围在[-10000, 10000](包括边界)。 26 | 27 | 例子: 28 | 29 | 输入: 30 | 31 | [[0,0],[1,0],[2,0]] 32 | 33 | 输出: 34 | 35 | 2 36 | 37 | 解释: 38 | 39 | 两个回旋镖分别是:[[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]] 40 | 41 | #### 分析 42 | 43 | 抓住两组点 (x1,y1)、(x2,y2) 和 (x1,y1)、(x3,y3) 之间的距离相等这个信息:distance = sqrt{(x1-x2)^2+(y1-y2)^2} = sqrt{(x1-x3)^2+(y1-y3)^2} 44 | 45 | 按照这种相等的距离,我们可以给所有点进行分类,相同距离的这些点(假设n个)可以构成一个排列组合中的排列:n*(n-1)个回旋镖。 46 | 47 | #### 代码 48 | 49 | Python代码: 50 | 51 | ```Python 52 | class Solution(object): 53 | def numberOfBoomerangs(self, points): 54 | """ 55 | :type points: List[List[int]] 56 | :rtype: int 57 | """ 58 | ans = 0 59 | for x1,y1 in points: 60 | dmap = collections.defaultdict(int) 61 | for x2,y2 in points: 62 | dmap[(x1-x2)**2+(y1-y2)**2] += 1 63 | for d in dmap: 64 | ans += dmap[d]*(dmap[d]-1) 65 | return ans 66 | ``` 67 | 68 | C++代码: 69 | 70 | ```C++ 71 | class Solution { 72 | public: 73 | int numberOfBoomerangs(vector>& points) { 74 | int ans = 0; 75 | unordered_map hash; 76 | for(int i=0;i map = new HashMap(); 97 | for(int i=0;i= W. 7 | 3. The difference between length L and width W should be as small as possible. 8 | 9 | You need to output the length L and the width W of the web page you designed in sequence. 10 | 11 | Example: 12 | 13 | Input: 4 14 | 15 | Output: [2, 2] 16 | 17 | Explanation: The target area is 4, and all the possible ways to construct it are [1,4], [2,2], [4,1]. 18 | But according to requirement 2, [1,4] is illegal; according to requirement 3, [4,1] is not optimal compared to [2,2]. So the length L is 2, and the width W is 2. 19 | 20 | Note: 21 | 22 | - The given area won't exceed 10,000,000 and is a positive integer 23 | - The web page's width and length you designed must be positive integers. 24 | 25 | #### 翻译 26 | 27 | 作为一个web开发人员,知道怎样去设计一个网页的大小是非常重要的。所以,给定一个特定的矩形网页区域,你现在的工作就是去设计一个矩形网页,它的长度L和宽度W满足以下需求: 28 | 29 | 1. 你设计的矩形网页的面积必须等于给定的目标面积。 30 | 2. 宽度W不应该比长度L大,也就是说L >=W 。 31 | 3. 长度L和宽度W的差值应该尽可能的小。 32 | 33 | 你需要按顺序输出你设计的网页的长度L和宽度W 34 | 35 | 例子: 36 | 37 | 输入:4 38 | 39 | 输出:[2, 2] 40 | 41 | 解释:目标面积是4,所有的可能去构造矩形的方法有:[1,4], [2,2], [4,1]. 42 | 但是依据第二条需求,[1,4]是非法的;根据第三条需求,[4,1]不是最优的相比于[2,2]。所以长度L是2,宽度W是2. 43 | 44 | 注意: 45 | 46 | - 给出的面积不会超过10,000,000 并且是正整数 47 | - 你设计的网页的长度和宽度必须是正整数。 48 | 49 | #### 代码 50 | 51 | ```java 52 | public class Solution { 53 | public int[] constructRectangle(int area) { 54 | int[] array = new int[2]; 55 | for(int i=1;i<=(int)Math.sqrt(area);i++){ 56 | if(area%i == 0){ 57 | array[0] = area/i; 58 | array[1] = i; 59 | } 60 | } 61 | return array; 62 | } 63 | } 64 | ``` 65 | 66 | ```C++ 67 | class Solution { 68 | public: 69 | vector constructRectangle(int area) { 70 | vector array(2); 71 | for(int i=1;i<=sqrt(area);i++){ 72 | if(area%i == 0){ 73 | array[0]=area/i; 74 | array[1]=i; 75 | } 76 | } 77 | return array; 78 | } 79 | }; 80 | ``` 81 | 82 | ```Python 83 | class Solution(object): 84 | def constructRectangle(self, area): 85 | """ 86 | :type area: int 87 | :rtype: List[int] 88 | """ 89 | array=[1]*2; 90 | for i in range(1,int(math.sqrt(area))+1): 91 | if(area%i==0): 92 | array[0]=area/i; 93 | array[1]=i; 94 | return array 95 | ``` 96 | -------------------------------------------------------------------------------- /第一遍/496. Next Greater Element I.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | You are given two arrays **(without duplicates)** `nums1` and `nums2` where `nums1`’s elements are subset of `nums2`. Find all the next greater numbers for `nums1`'s elements in the corresponding places of `nums2`. 4 | 5 | The Next Greater Number of a number **x** in `nums1` is the first greater number to its right in `nums2`. If it does not exist, output -1 for this number. 6 | 7 | **Example 1:** 8 | ``` 9 | Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. 10 | Output: [-1,3,-1] 11 | Explanation: 12 | For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. 13 | For number 1 in the first array, the next greater number for it in the second array is 3. 14 | For number 2 in the first array, there is no next greater number for it in the second array, so output -1. 15 | ``` 16 | 17 | **Example 2:** 18 | ``` 19 | Input: nums1 = [2,4], nums2 = [1,2,3,4]. 20 | Output: [3,-1] 21 | Explanation: 22 | For number 2 in the first array, the next greater number for it in the second array is 3. 23 | For number 4 in the first array, there is no next greater number for it in the second array, so output -1. 24 | ``` 25 | 26 | **Note:** 27 | 28 | 1. All elements in `nums1` and `nums2` are unique. 29 | 2. The length of both `nums1` and `nums2` would not exceed 1000. 30 | 31 | [题目地址](https://leetcode.com/problems/next-greater-element-i/) 32 | 33 | ## 讲解 34 | 35 | 这道题主要就是考察立flag的能力(首次进入)。 36 | 37 | ## java代码 38 | 39 | ```java 40 | class Solution { 41 | public int[] nextGreaterElement(int[] nums1, int[] nums2) { 42 | int[] result = new int[nums1.length]; 43 | for(int i=0;inums1[i]){ 53 | result[i] = nums2[j]; 54 | break; 55 | } 56 | } 57 | } 58 | return result; 59 | } 60 | } 61 | ``` -------------------------------------------------------------------------------- /第一遍/508. Most Frequent Subtree Sum.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order. 4 | 5 | **Examples 1** 6 | Input: 7 | ``` 8 | 5 9 | / \ 10 | 2 -3 11 | ``` 12 | return [2, -3, 4], since all the values happen only once, return all of them in any order. 13 | **Examples 2** 14 | Input: 15 | ``` 16 | 5 17 | / \ 18 | 2 -5 19 | ``` 20 | return [2], since 2 happens twice, however -5 only occur once. 21 | **Note:** You may assume the sum of values in any subtree is in the range of 32-bit signed integer. 22 | 23 | [题目地址](https://leetcode.com/problems/most-frequent-subtree-sum/) 24 | 25 | ## 讲解 26 | 27 | 典型的递归题,写起来唯一比较麻烦的点在于,输出map中最大的value所对应的key,还好不是排序,只是找最大的,如果要排序的话可以构造一个pair对象,然后对pair对象组成的组数排序,然后写compare函数的时候,依据value比较大小就行了。我用了一个最朴素的方法,先遍历一遍map找最大的value,然后再遍历一遍map找所有最大的value。还有java写List转int数组的时候也是挺坑的,没有库函数可用,我就只好自己写了。 28 | 29 | ## java代码 30 | 31 | ```java 32 | /** 33 | * Definition for a binary tree node. 34 | * public class TreeNode { 35 | * int val; 36 | * TreeNode left; 37 | * TreeNode right; 38 | * TreeNode(int x) { val = x; } 39 | * } 40 | */ 41 | class Solution { 42 | private Map map = new HashMap<>(); 43 | private List result = new ArrayList<>(); 44 | public int[] findFrequentTreeSum(TreeNode root) { 45 | recurse(root); 46 | int max = 0; 47 | for(Integer x:map.keySet()){ 48 | if(map.get(x)>max){ 49 | max = map.get(x); 50 | } 51 | } 52 | for(Integer x:map.keySet()){ 53 | if(map.get(x)==max){ 54 | result.add(x); 55 | } 56 | } 57 | int[] res = new int[result.size()]; 58 | for(int i=0;i 1. 7 | ``` 8 | Given `N`, calculate `F(N)`. 9 | 10 | **Example 1:** 11 | ``` 12 | Input: 2 13 | Output: 1 14 | Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1. 15 | ``` 16 | 17 | **Example 2:** 18 | ``` 19 | Input: 3 20 | Output: 2 21 | Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2. 22 | ``` 23 | 24 | **Example 3:** 25 | ``` 26 | Input: 4 27 | Output: 3 28 | Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3. 29 | ``` 30 | 31 | **Note:** 32 | 33 | 0 ≤ `N` ≤ 30. 34 | 35 | ## 讲解 36 | 37 | 斐波那契数列的算法有很多种,有递归,有迭代,递归很慢会有很多重复计算的部分,时间复杂度是 O($2^N$),迭代很快时间复杂度是: O(N)。最快的算法是一种用到矩阵的算法,只要O(logN)的复杂度。 38 | 39 | 我这里用了递归+记录,省掉了重复计算的部分,效率变快不少。 40 | 41 | ## java代码 42 | 43 | ```java 44 | class Solution { 45 | private Map map = new HashMap<>(); 46 | public int fib(int N) { 47 | if(N==0){ 48 | return 0; 49 | }else if(N==1){ 50 | return 1; 51 | } 52 | if(map.get(N)!=null){ 53 | return map.get(N); 54 | } 55 | int fibN = fib(N-1)+fib(N-2); 56 | map.put(N, fibN); 57 | return fibN; 58 | } 59 | } 60 | ``` -------------------------------------------------------------------------------- /第一遍/513. Find Bottom Left Tree Value.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a binary tree, find the leftmost value in the last row of the tree. 4 | 5 | **Example 1:** 6 | ``` 7 | Input: 8 | 9 | 2 10 | / \ 11 | 1 3 12 | 13 | Output: 14 | 1 15 | ``` 16 | 17 | **Example 2:** 18 | ``` 19 | Input: 20 | 21 | 1 22 | / \ 23 | 2 3 24 | / / \ 25 | 4 5 6 26 | / 27 | 7 28 | 29 | Output: 30 | 7 31 | ``` 32 | 33 | **Note:** You may assume the tree (i.e., the given root node) is not **NULL**. 34 | 35 | [题目地址](https://leetcode.com/problems/find-bottom-left-tree-value/) 36 | 37 | ## 讲解 38 | 39 | 这道题感觉挺简单的,首先我想到的是一定要选深度最大的节点,然后他要最左边的,那么我们可以先右后左的进行遍历,最后左边就可以覆盖右边了。 40 | 41 | ## java代码 42 | 43 | ```java 44 | /** 45 | * Definition for a binary tree node. 46 | * public class TreeNode { 47 | * int val; 48 | * TreeNode left; 49 | * TreeNode right; 50 | * TreeNode(int x) { val = x; } 51 | * } 52 | */ 53 | class Solution { 54 | private int result; 55 | private int maxDepth=0; 56 | public int findBottomLeftValue(TreeNode root) { 57 | inOrder(root, 0); 58 | return result; 59 | } 60 | 61 | private void inOrder(TreeNode root, int depth){ 62 | if(root==null){ 63 | return; 64 | } 65 | if(maxDepth<=depth){ 66 | maxDepth=depth; 67 | result = root.val; 68 | } 69 | if(root.right!=null){ 70 | inOrder(root.right, depth+1); 71 | } 72 | if(root.left!=null){ 73 | inOrder(root.left, depth+1); 74 | } 75 | } 76 | } 77 | ``` -------------------------------------------------------------------------------- /第一遍/515. Find Largest Value in Each Tree Row.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | You need to find the largest value in each row of a binary tree. 4 | 5 | **Example:** 6 | ``` 7 | Input: 8 | 9 | 1 10 | / \ 11 | 3 2 12 | / \ \ 13 | 5 3 9 14 | 15 | Output: [1, 3, 9] 16 | ``` 17 | 18 | ## 讲解 19 | 20 | 又是树的层次遍历题。相同的题我已经做了两个了:[637. Average of Levels in Binary Tree](https://segmentfault.com/a/1190000017740661)、[429. N-ary Tree Level Order Traversal](https://segmentfault.com/a/1190000017718580) 21 | 22 | ## Java代码 23 | 24 | ```java 25 | /** 26 | * Definition for a binary tree node. 27 | * public class TreeNode { 28 | * int val; 29 | * TreeNode left; 30 | * TreeNode right; 31 | * TreeNode(int x) { val = x; } 32 | * } 33 | */ 34 | class Solution { 35 | List result = new ArrayList<>(); 36 | public List largestValues(TreeNode root) { 37 | if(root==null){ 38 | return result; 39 | } 40 | Queue queue = new LinkedList<>(); 41 | queue.offer(root); 42 | int count = 1; 43 | while(!queue.isEmpty()){ 44 | List list = new ArrayList<>(); 45 | int floorSize = 0; 46 | for(int i=0;i=pos && i%pos==0 || i children; 32 | 33 | public Node() {} 34 | 35 | public Node(int _val,List _children) { 36 | val = _val; 37 | children = _children; 38 | } 39 | }; 40 | */ 41 | class Solution { 42 | private int result=0; 43 | private boolean flag = true; 44 | public int maxDepth(Node root) { 45 | if(root==null){ 46 | return result; 47 | } 48 | if(flag){ 49 | root.val=1; 50 | flag = false; 51 | } 52 | if(result set = new HashSet<>(); 40 | for(int x:candies){ 41 | set.add(x); 42 | } 43 | int result=0; 44 | if(set.size()>candies.length/2){ 45 | result = candies.length/2; 46 | }else{ 47 | result = set.size(); 48 | } 49 | return result; 50 | } 51 | } 52 | ``` -------------------------------------------------------------------------------- /第一遍/589. N-ary Tree Preorder Traversal.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given an n-ary tree, return the preorder traversal of its nodes' values. 4 | 5 | For example, given a `3-ary` tree: 6 | 7 | ![](https://assets.leetcode.com/uploads/2018/10/12/narytreeexample.png) 8 | 9 | Return its preorder traversal as: `[1,3,5,6,2,4]`. 10 | 11 | 12 | 13 | **Note:** 14 | 15 | Recursive solution is trivial, could you do it iteratively? 16 | 17 | [题目地址](https://leetcode.com/problems/n-ary-tree-preorder-traversal/) 18 | 19 | ## 讲解 20 | 21 | 如果用递归来解题的话,还是非常简单的。如果要用迭代来解题,无非就是用栈来实现。要注意的一点是,需要一个额外的栈来把压栈的顺序倒一下序。 22 | 23 | ## Java代码 24 | 25 | 递归代码: 26 | ```java 27 | /* 28 | // Definition for a Node. 29 | class Node { 30 | public int val; 31 | public List children; 32 | 33 | public Node() {} 34 | 35 | public Node(int _val,List _children) { 36 | val = _val; 37 | children = _children; 38 | } 39 | }; 40 | */ 41 | class Solution { 42 | private List result = new ArrayList<>(); 43 | public List preorder(Node root) { 44 | if(root==null){ 45 | return result; 46 | } 47 | result.add(root.val); 48 | for(Node node:root.children){ 49 | preorder(node); 50 | } 51 | return result; 52 | } 53 | } 54 | ``` 55 | 56 | 迭代代码: 57 | ```java 58 | /* 59 | // Definition for a Node. 60 | class Node { 61 | public int val; 62 | public List children; 63 | 64 | public Node() {} 65 | 66 | public Node(int _val,List _children) { 67 | val = _val; 68 | children = _children; 69 | } 70 | }; 71 | */ 72 | class Solution { 73 | private List result = new ArrayList<>(); 74 | private Stack stack = new Stack<>(); 75 | private Stack stack_temp = new Stack(); 76 | public List preorder(Node root) { 77 | if(root==null){ 78 | return result; 79 | } 80 | stack.push(root); 81 | while(!stack.empty()){ 82 | Node theNode = stack.pop(); 83 | result.add(theNode.val); 84 | for(Node node:theNode.children){ 85 | stack_temp.push(node); 86 | } 87 | while(!stack_temp.empty()){ 88 | stack.push(stack_temp.pop()); 89 | } 90 | } 91 | return result; 92 | } 93 | } 94 | ``` -------------------------------------------------------------------------------- /第一遍/590. N-ary Tree Postorder Traversal.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given an n-ary tree, return the postorder traversal of its nodes' values. 4 | 5 | For example, given a `3-ary` tree: 6 | 7 | ![](https://assets.leetcode.com/uploads/2018/10/12/narytreeexample.png) 8 | 9 | Return its postorder traversal as: `[5,6,3,2,4,1]`. 10 | 11 | 12 | **Note:** 13 | 14 | Recursive solution is trivial, could you do it iteratively? 15 | 16 | [题目地址](https://leetcode.com/problems/n-ary-tree-postorder-traversal/) 17 | 18 | ## 讲解 19 | 20 | 这道题跟先序遍历差不多,调换一下添加结点的顺序而已。参考:[leetcode讲解--589. N-ary Tree Preorder Traversal](https://segmentfault.com/a/1190000017522199) 21 | 22 | 但这道题的迭代解法稍微有点麻烦,需要一个标记,初次访问一个结点的时候我们并不能立即将它的值加进结果里,而是要等它的所有孩子访问完毕再加。也就是说我们第一次访问它并不pop,第二次访问它才pop。 23 | 24 | ## Java代码 25 | 26 | 递归解法: 27 | ```java 28 | /* 29 | // Definition for a Node. 30 | class Node { 31 | public int val; 32 | public List children; 33 | 34 | public Node() {} 35 | 36 | public Node(int _val,List _children) { 37 | val = _val; 38 | children = _children; 39 | } 40 | }; 41 | */ 42 | class Solution { 43 | private List result = new ArrayList<>(); 44 | public List postorder(Node root) { 45 | if(root==null){ 46 | return result; 47 | } 48 | for(Node node:root.children){ 49 | postorder(node); 50 | } 51 | result.add(root.val); 52 | return result; 53 | } 54 | } 55 | ``` 56 | 57 | 迭代解法: 58 | ```java 59 | /* 60 | // Definition for a Node. 61 | class Node { 62 | public int val; 63 | public List children; 64 | 65 | public Node() {} 66 | 67 | public Node(int _val,List _children) { 68 | val = _val; 69 | children = _children; 70 | } 71 | }; 72 | */ 73 | class Solution { 74 | private List result = new ArrayList<>(); 75 | private Stack stack = new Stack<>(); 76 | private Stack stack_temp = new Stack(); 77 | public List postorder(Node root) { 78 | if(root==null){ 79 | return result; 80 | } 81 | Bundle rootBundle = new Bundle(root); 82 | stack.push(rootBundle); 83 | while(!stack.empty()){ 84 | Bundle bundle = stack.peek(); 85 | if(bundle.flag){ 86 | result.add(stack.pop().node.val); 87 | continue; 88 | } 89 | for(Node node:bundle.node.children){ 90 | Bundle d = new Bundle(node); 91 | stack_temp.push(d); 92 | } 93 | while(!stack_temp.empty()){ 94 | stack.push(stack_temp.pop()); 95 | } 96 | bundle.flag = true; 97 | } 98 | return result; 99 | } 100 | 101 | class Bundle{ 102 | Node node; 103 | Boolean flag; 104 | public Bundle(Node node){ 105 | flag = false; 106 | this.node = node; 107 | } 108 | } 109 | } 110 | ``` 111 | 112 | -------------------------------------------------------------------------------- /第一遍/617. Merge Two Binary Trees.md: -------------------------------------------------------------------------------- 1 | ## 617. Merge Two Binary Trees 2 | 3 | Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. 4 | 5 | You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree. 6 | 7 | **Example 1:** 8 | 9 | ``` 10 | Input: 11 | Tree 1 Tree 2 12 | 1 2 13 | / \ / \ 14 | 3 2 1 3 15 | / \ \ 16 | 5 4 7 17 | Output: 18 | Merged tree: 19 | 3 20 | / \ 21 | 4 5 22 | / \ \ 23 | 5 4 7 24 | ``` 25 | 26 | **Note:** The merging process must start from the root nodes of both trees. 27 | 28 | 这一题主要考察的点有两个: 29 | 1. 二叉树的遍历 30 | 2. 分类讨论的能力 31 | 32 | ## java代码 33 | 34 | ```java 35 | /** 36 | * Definition for a binary tree node. 37 | * public class TreeNode { 38 | * int val; 39 | * TreeNode left; 40 | * TreeNode right; 41 | * TreeNode(int x) { val = x; } 42 | * } 43 | */ 44 | class Solution { 45 | public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { 46 | if(t1==null && t2==null){ 47 | return null; 48 | }else if(t1==null && t2!=null){ 49 | t1 = new TreeNode(t2.val); 50 | t1.left = mergeTrees(null, t2.left); 51 | t1.right = mergeTrees(null, t2.right); 52 | }else if(t1!=null && t2!=null){ 53 | t1.val = t1.val+t2.val; 54 | t1.left = mergeTrees(t1.left, t2.left); 55 | t1.right = mergeTrees(t1.right, t2.right); 56 | }else{ 57 | t1.left = mergeTrees(t1.left, null); 58 | t1.right = mergeTrees(t1.right, null); 59 | } 60 | return t1; 61 | } 62 | } 63 | ``` -------------------------------------------------------------------------------- /第一遍/637. Average of Levels in Binary Tree.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array. 4 | 5 | **Example 1:** 6 | ``` 7 | Input: 8 | 3 9 | / \ 10 | 9 20 11 | / \ 12 | 15 7 13 | Output: [3, 14.5, 11] 14 | Explanation: 15 | The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11]. 16 | ``` 17 | 18 | **Note:** 19 | 1. The range of node's value is in the range of 32-bit signed integer. 20 | 21 | ## 讲解 22 | 23 | 这题跟[429. N-ary Tree Level Order Traversal](https://segmentfault.com/a/1190000017718580)很像。都是广度优先遍历树(也就是按层级遍历树)。 24 | 25 | ## java代码 26 | 27 | ```java 28 | /** 29 | * Definition for a binary tree node. 30 | * public class TreeNode { 31 | * int val; 32 | * TreeNode left; 33 | * TreeNode right; 34 | * TreeNode(int x) { val = x; } 35 | * } 36 | */ 37 | class Solution { 38 | List result = new ArrayList<>(); 39 | public List averageOfLevels(TreeNode root) { 40 | if(root==null){ 41 | return result; 42 | } 43 | Queue queue = new LinkedList<>(); 44 | queue.offer(root); 45 | int children_num=1; 46 | while(!queue.isEmpty()){ 47 | double sum = 0; 48 | int count=0; 49 | for(int i=0;i result = new ArrayList<>(); 59 | for(String s:ops){ 60 | switch(s){ 61 | case "+": 62 | result.add(result.get(result.size()-1)+result.get(result.size()-2)); 63 | break; 64 | case "D": 65 | result.add(result.get(result.size()-1)*2); 66 | break; 67 | case "C": 68 | result.remove(result.size()-1); 69 | break; 70 | default: 71 | result.add(Integer.parseInt(s)); 72 | } 73 | } 74 | int sum = 0; 75 | for(int i=0;i0){ 56 | if(flag){ 57 | now = temp%2; 58 | temp >>= 1; 59 | flag = false; 60 | }else{ 61 | previous = now; 62 | now = temp%2; 63 | if(previous==now){ 64 | return false; 65 | } 66 | temp >>= 1; 67 | } 68 | } 69 | return true; 70 | } 71 | } 72 | ``` -------------------------------------------------------------------------------- /第一遍/700. Search in a Binary Search Tree.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given the root node of a binary search tree (BST) and a value. You need to find the node in the BST that the node's value equals the given value. Return the subtree rooted with that node. If such node doesn't exist, you should return NULL. 4 | 5 | For example, 6 | ``` 7 | Given the tree: 8 | 4 9 | / \ 10 | 2 7 11 | / \ 12 | 1 3 13 | ``` 14 | And the value to search: 2 15 | You should return this subtree: 16 | ``` 17 | 2 18 | / \ 19 | 1 3 20 | ``` 21 | In the example above, if we want to search the value `5`, since there is no node with value `5`, we should return `NULL`. 22 | 23 | Note that an empty tree is represented by `NULL`, therefore you would see the expected output (serialized tree format) as `[]`, not `null`. 24 | 25 | [题目地址](https://leetcode.com/problems/search-in-a-binary-search-tree/) 26 | 27 | ## 讲解 28 | 29 | 要注意一下的是,如果我们`searchBST`作为递归函数,我们就要返回一个TreeNode类型,虽然返回,但我们不一定会用到。如果我们找到了,就把treeNode标记为结果结点。 30 | 31 | ## Java代码 32 | 33 | ```java 34 | /** 35 | * Definition for a binary tree node. 36 | * public class TreeNode { 37 | * int val; 38 | * TreeNode left; 39 | * TreeNode right; 40 | * TreeNode(int x) { val = x; } 41 | * } 42 | */ 43 | class Solution { 44 | private TreeNode treeNode; 45 | public TreeNode searchBST(TreeNode root, int val) { 46 | if(root==null){ 47 | return treeNode; 48 | } 49 | if(root.val == val){ 50 | treeNode = root; 51 | } 52 | searchBST(root.left, val); 53 | searchBST(root.right, val); 54 | return treeNode; 55 | } 56 | } 57 | ``` -------------------------------------------------------------------------------- /第一遍/701. Insert into a Binary Search Tree.md: -------------------------------------------------------------------------------- 1 | ## 701. Insert into a Binary Search Tree 2 | 3 | Given the root node of a binary search tree (BST) and a value to be inserted into the tree, insert the value into the BST. Return the root node of the BST after the insertion. It is guaranteed that the new value does not exist in the original BST. 4 | 5 | Note that there may exist multiple valid ways for the insertion, as long as the tree remains a BST after insertion. You can return any of them. 6 | 7 | For example, 8 | 9 | ``` 10 | Given the tree: 11 | 4 12 | / \ 13 | 2 7 14 | / \ 15 | 1 3 16 | And the value to insert: 5 17 | ``` 18 | 19 | You can return this binary search tree: 20 | 21 | ``` 22 | 4 23 | / \ 24 | 2 7 25 | / \ / 26 | 1 3 5 27 | ``` 28 | 29 | This tree is also valid: 30 | 31 | ``` 32 | 5 33 | / \ 34 | 2 7 35 | / \ 36 | 1 3 37 | \ 38 | 4 39 | ``` 40 | 41 | 二叉查找树的插入,挺简单的。 42 | 43 | ## java代码 44 | 45 | ```java 46 | /** 47 | * Definition for a binary tree node. 48 | * public class TreeNode { 49 | * int val; 50 | * TreeNode left; 51 | * TreeNode right; 52 | * TreeNode(int x) { val = x; } 53 | * } 54 | */ 55 | class Solution { 56 | public TreeNode insertIntoBST(TreeNode root, int val) { 57 | if(root==null){ 58 | return new TreeNode(val); 59 | } 60 | if(val>root.val){ 61 | root.right = insertIntoBST(root.right, val); 62 | }else{ 63 | root.left = insertIntoBST(root.left, val); 64 | } 65 | return root; 66 | } 67 | } 68 | ``` -------------------------------------------------------------------------------- /第一遍/706. Design HashMap.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Design a HashMap without using any built-in hash table libraries. 4 | 5 | To be specific, your design should include these functions: 6 | 7 | - `put(key, value)` : Insert a (key, value) pair into the HashMap. If the value already exists in the HashMap, update the value. 8 | - `get(key)`: Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key. 9 | - `remove(key)` : Remove the mapping for the value key if this map contains the mapping for the key. 10 | 11 | **Example:** 12 | ``` 13 | MyHashMap hashMap = new MyHashMap(); 14 | hashMap.put(1, 1); 15 | hashMap.put(2, 2); 16 | hashMap.get(1); // returns 1 17 | hashMap.get(3); // returns -1 (not found) 18 | hashMap.put(2, 1); // update the existing value 19 | hashMap.get(2); // returns 1 20 | hashMap.remove(2); // remove the mapping for 2 21 | hashMap.get(2); // returns -1 (not found) 22 | ``` 23 | 24 | **Note:** 25 | 26 | - All keys and values will be in the range of `[0, 1000000]`. 27 | - The number of operations will be in the range of `[1, 10000]`. 28 | - Please do not use the built-in HashMap library. 29 | 30 | [题目地址](https://leetcode.com/problems/design-hashmap/) 31 | 32 | ## 讲解 33 | 34 | 这道题的意思是要自己实现一个hashmap,java的hashmap是用拉链法解决hash冲突的,每个链采用的数据结构是红黑树。但这里是一道简单题,显然用不到这么复杂的东西。其实最简单的hashmap直接用一个数组就可以了(不用考虑hash冲突其实是很简单的)。 35 | 36 | ## java代码 37 | 38 | ```java 39 | class MyHashMap { 40 | 41 | private int[] container = new int[1000001]; 42 | 43 | /** Initialize your data structure here. */ 44 | public MyHashMap() { 45 | for(int i=0;i selfDividingNumbers(int left, int right) { 32 | List result = new ArrayList<>(); 33 | for(int i=left;i<=right;i++){ 34 | boolean flag = true; 35 | int num=i; 36 | while(num!=0){ 37 | int n = num%10; 38 | if(n==0 || i%n!=0){ 39 | flag = false; 40 | break; 41 | } 42 | num=num/10; 43 | } 44 | if(flag){ 45 | result.add(i); 46 | } 47 | } 48 | return result; 49 | } 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /第一遍/739. Daily Temperatures.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a list of daily temperatures `T`, return a list such that, for each day in the input, tells you how many days you would have to wait until a warmer temperature. If there is no future day for which this is possible, put `0` instead. 4 | 5 | For example, given the list of temperatures `T = [73, 74, 75, 71, 69, 72, 76, 73]`, your output should be `[1, 1, 4, 2, 1, 1, 0, 0]`. 6 | 7 | **Note:** The length of `temperatures` will be in the range `[1, 30000]`. Each temperature will be an integer in the range `[30, 100]`. 8 | 9 | [题目地址](https://leetcode.com/problems/daily-temperatures/) 10 | 11 | ## 讲解 12 | 13 | 这道题挺简单的,往后找比当前温度大的就行了。 14 | 15 | ## Java代码 16 | 17 | ```java 18 | class Solution { 19 | public int[] dailyTemperatures(int[] T) { 20 | int[] result = new int[T.length]; 21 | for(int i=0;i results = new ArrayList<>(); 47 | for(int i=0;i map = new HashMap<>(); 49 | for(int j=0;j0){ 60 | map.put(Character.toLowerCase(licensePlate.charAt(j)), map.get(Character.toLowerCase(licensePlate.charAt(j)))-1); 61 | }else{ 62 | break; 63 | } 64 | } 65 | } 66 | if(j==licensePlate.length()){ 67 | results.add(i); 68 | } 69 | } 70 | int min = 15; 71 | int record = 0; 72 | for(Integer x:results){ 73 | if(words[x].length() 110 (2 set bits, 2 is prime) 13 | 7 -> 111 (3 set bits, 3 is prime) 14 | 9 -> 1001 (2 set bits , 2 is prime) 15 | 10->1010 (2 set bits , 2 is prime) 16 | ``` 17 | 18 | **Example 2:** 19 | ``` 20 | Input: L = 10, R = 15 21 | Output: 5 22 | Explanation: 23 | 10 -> 1010 (2 set bits, 2 is prime) 24 | 11 -> 1011 (3 set bits, 3 is prime) 25 | 12 -> 1100 (2 set bits, 2 is prime) 26 | 13 -> 1101 (3 set bits, 3 is prime) 27 | 14 -> 1110 (3 set bits, 3 is prime) 28 | 15 -> 1111 (4 set bits, 4 is not prime) 29 | ``` 30 | 31 | **Note:** 32 | 1. `L, R` will be integers `L <= R` in the range `[1, 10^6]`. 33 | 2. `R - L` will be at most 10000. 34 | 35 | [题目地址](https://leetcode.com/problems/prime-number-of-set-bits-in-binary-representation/) 36 | 37 | ## 讲解 38 | 39 | 这一题同样是针对二进制表示进行出题,题目的意思是计算一个数的二进制表示中有多少个1,如果是素数个1,结果就加一。性能的提升点应该是在 `isPrime` 函数的实现上。我采用的是最普通的方法,从2到$\sqrt x$进行累加,判断x是否是素数,效率比较低。 40 | 41 | ## java代码 42 | 43 | ```java 44 | class Solution { 45 | public int countPrimeSetBits(int L, int R) { 46 | int result = 0; 47 | for(int i=L;i<=R;i++){ 48 | int temp = i; 49 | int count = 0; 50 | while(temp>0){ 51 | if(temp%2==1){ 52 | count++; 53 | } 54 | temp >>= 1; 55 | } 56 | if(isPrime(count)){ 57 | result++; 58 | } 59 | } 60 | return result; 61 | } 62 | 63 | private boolean isPrime(int a){ 64 | if(a<=1){ 65 | return false; 66 | } 67 | for(int i=2;i<=Math.sqrt(a);i++){ 68 | if(a%i==0){ 69 | return false; 70 | } 71 | } 72 | return true; 73 | } 74 | } 75 | ``` -------------------------------------------------------------------------------- /第一遍/763. Partition Labels.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | A string `S` of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts. 4 | 5 | **Example 1:** 6 | ``` 7 | Input: S = "ababcbacadefegdehijhklij" 8 | Output: [9,7,8] 9 | Explanation: 10 | The partition is "ababcbaca", "defegde", "hijhklij". 11 | This is a partition so that each letter appears in at most one part. 12 | A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts. 13 | ``` 14 | 15 | **Note:** 16 | 17 | 1. `S` will have length in range `[1, 500]`. 18 | 2. `S` will consist of lowercase letters (`'a'` to `'z'`) only. 19 | 20 | [题目地址](https://leetcode.com/problems/partition-labels/) 21 | 22 | ## 讲解 23 | 24 | 这道题我居然一遍过,以前做题或多或少有些小错误。这道题我一上手就发现应该尽量阻止对数据的多次遍历,所以如果能遍历一遍得到一些有用的信息就好了。我用的解法是,建立一个map存储每个字母的首尾位置(当然实际操作中我用的是两个map分别存储字母第一次出现的位置和最后一次出现的位置)。然后如果这一段之间出现了一个字母,它的尾部位置比框住它的这个字母更大,就更新尾部位置,直到尾部位置无法再扩大为止。 25 | 26 | ## Java代码 27 | 28 | ```java 29 | class Solution { 30 | public List partitionLabels(String S) { 31 | List result = new ArrayList<>(); 32 | char[] c = S.toCharArray(); 33 | Map mapStart = new HashMap<>(); 34 | Map mapEnd = new HashMap<>(); 35 | for(int i=0;iendIndex){ 48 | endIndex = mapEnd.get(c[i]); 49 | } 50 | } 51 | result.add(endIndex-beginIndex+1); 52 | beginIndex = endIndex+1; 53 | } 54 | return result; 55 | } 56 | } 57 | ``` -------------------------------------------------------------------------------- /第一遍/766. Toeplitz Matrix.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | A matrix is Toeplitz if every diagonal from top-left to bottom-right has the same element. 4 | 5 | Now given an `M x N` matrix, return `True` if and only if the matrix is Toeplitz. 6 | 7 | 8 | **Example 1:** 9 | ``` 10 | Input: 11 | matrix = [ 12 | [1,2,3,4], 13 | [5,1,2,3], 14 | [9,5,1,2] 15 | ] 16 | Output: True 17 | ``` 18 | 19 | **Explanation:** 20 | ``` 21 | In the above grid, the diagonals are: 22 | "[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]". 23 | In each diagonal all elements are the same, so the answer is True. 24 | ``` 25 | 26 | **Example 2:** 27 | ``` 28 | Input: 29 | matrix = [ 30 | [1,2], 31 | [2,2] 32 | ] 33 | Output: False 34 | Explanation: 35 | The diagonal "[1, 2]" has different elements. 36 | ``` 37 | 38 | **Note:** 39 | 40 | - `matrix` will be a 2D array of integers. 41 | - `matrix` will have a number of rows and columns in range `[1, 20]`. 42 | - `matrix[i][j]` will be integers in range `[0, 99]`. 43 | 44 | **Follow up:** 45 | 46 | 1. What if the matrix is stored on disk, and the memory is limited such that you can only load at most one row of the matrix into the memory at once? 47 | 2. What if the matrix is so large that you can only load up a partial row into the memory at once? 48 | 49 | ## 讲解 50 | 51 | 这道题我一开始在while里面只用了一个限制条件,后来发现不行的。其实多加一些可能会出现的条件是一种很好的习惯。 52 | 53 | ## Java代码 54 | 55 | ```java 56 | class Solution { 57 | public boolean isToeplitzMatrix(int[][] matrix) { 58 | for(int i=0;i JMap = new HashMap<>(); 43 | for(Character c:J.toCharArray()){ 44 | JMap.put(c, 0); 45 | } 46 | for(Character c:S.toCharArray()){ 47 | Integer count = JMap.get(c); 48 | if(count!=null){ 49 | result++; 50 | } 51 | } 52 | return result; 53 | } 54 | } 55 | ``` -------------------------------------------------------------------------------- /第一遍/784. Letter Case Permutation.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. Return a list of all possible strings we could create. 4 | 5 | ``` 6 | Examples: 7 | Input: S = "a1b2" 8 | Output: ["a1b2", "a1B2", "A1b2", "A1B2"] 9 | 10 | Input: S = "3z4" 11 | Output: ["3z4", "3Z4"] 12 | 13 | Input: S = "12345" 14 | Output: ["12345"] 15 | ``` 16 | 17 | **Note:** 18 | 19 | 1. `S` will be a string with length between `1` and `12`. 20 | 2. `S` will consist only of letters or digits. 21 | 22 | [题目地址](https://leetcode.com/problems/letter-case-permutation/) 23 | 24 | ## 讲解 25 | 26 | 这个题目的生成是一个树形结构,只取树的叶子节点。我用了递归来解题。 27 | 28 | ## Java代码 29 | 30 | 代码有重复的部分,感觉很丑 31 | 32 | ```java 33 | class Solution { 34 | private List result; 35 | public List letterCasePermutation(String S) { 36 | result = new ArrayList<>(); 37 | int i=0; 38 | for(;i'9'){ 40 | break; 41 | } 42 | } 43 | if(i'9'){ 63 | break; 64 | } 65 | } 66 | if(i mapT = new HashMap<>(); 37 | Set mapS = new HashSet<>(); 38 | for(int i=0;i0){ 65 | result[indexBegin++] = S.charAt(i); 66 | count--; 67 | } 68 | mapT.remove(S.charAt(i)); 69 | } 70 | } 71 | for(Character c:mapT.keySet()){ 72 | Integer count = mapT.get(c); 73 | while(count<0){ 74 | result[indexEnd--] = c; 75 | count++; 76 | } 77 | } 78 | return String.valueOf(result); 79 | } 80 | } 81 | ``` -------------------------------------------------------------------------------- /第一遍/797. All Paths From Source to Target.md: -------------------------------------------------------------------------------- 1 | ## 797. All Paths From Source to Target 2 | 3 | Given a directed, acyclic graph of `N` nodes. Find all possible paths from node 0 to node `N-1`, and return them in any order. 4 | 5 | The graph is given as follows: the nodes are 0, 1, ..., graph.length - 1. graph[i] is a list of all nodes j for which the edge (i, j) exists. 6 | 7 | ``` 8 | Example: 9 | Input: [[1,2], [3], [3], []] 10 | Output: [[0,1,3],[0,2,3]] 11 | Explanation: The graph looks like this: 12 | 0--->1 13 | | | 14 | v v 15 | 2--->3 16 | There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3. 17 | ``` 18 | 19 | **Note:** 20 | 21 | - The number of nodes in the graph will be in the range `[2, 15]`. 22 | - You can print different paths in any order, but you should keep the order of nodes inside one path. 23 | 24 | 这一题考察的是图的深度优先遍历,要注意的点是:回溯的时候如何清除掉record中的数据,只保留到当前节点的数据,之后的数据需要重新填充。刚开始我是用的一个record,企图通过清空当前节点之后的数据,后来发现不对,record必须是多个,否则我给result添加的record就会全部相同。所以只能通过new和深拷贝来完成这个目标。 25 | 26 | ## java代码 27 | 28 | ```java 29 | class Solution { 30 | List> result = new LinkedList>(); 31 | public List> allPathsSourceTarget(int[][] graph) { 32 | int index=0; 33 | for(int x:graph[index]){ 34 | List record = new LinkedList<>(); 35 | record.add(0); 36 | record.add(x); 37 | depthFirst(graph, x, record); 38 | } 39 | return result; 40 | } 41 | 42 | public void depthFirst(int[][] graph, int index, List record){ 43 | if(index==graph.length-1){ 44 | result.add(record); 45 | return; 46 | } 47 | if(graph[index]==null){ 48 | return; 49 | } 50 | for(int x:graph[index]){ 51 | record.add(x); 52 | int size = record.size(); 53 | depthFirst(graph, x, record); 54 | List temp = new LinkedList(); 55 | for(int i=0;i100){ 64 | len = widths[c[i]-'a']; 65 | count++; 66 | }else if(len==100){ 67 | len = 0; 68 | count++; 69 | } 70 | } 71 | return new int[]{count, len}; 72 | } 73 | } 74 | ``` -------------------------------------------------------------------------------- /第一遍/807. Max Increase to Keep City Skyline.md: -------------------------------------------------------------------------------- 1 | ## 807. Max Increase to Keep City Skyline 2 | 3 | In a 2 dimensional array `grid`, each value `grid[i][j]` represents the height of a building located there. We are allowed to increase the height of any number of buildings, by any amount (the amounts can be different for different buildings). Height 0 is considered to be a building as well. 4 | 5 | At the end, the "skyline" when viewed from all four directions of the grid, i.e. top, bottom, left, and right, must be the same as the skyline of the original grid. A city's skyline is the outer contour of the rectangles formed by all the buildings when viewed from a distance. See the following example. 6 | 7 | What is the maximum total sum that the height of the buildings can be increased? 8 | 9 | ``` 10 | Example: 11 | Input: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]] 12 | Output: 35 13 | Explanation: 14 | The grid is: 15 | [ [3, 0, 8, 4], 16 | [2, 4, 5, 7], 17 | [9, 2, 6, 3], 18 | [0, 3, 1, 0] ] 19 | 20 | The skyline viewed from top or bottom is: [9, 4, 8, 7] 21 | The skyline viewed from left or right is: [8, 7, 9, 3] 22 | 23 | The grid after increasing the height of buildings without affecting skylines is: 24 | 25 | gridNew = [ [8, 4, 8, 7], 26 | [7, 4, 7, 7], 27 | [9, 4, 8, 7], 28 | [3, 3, 3, 3] ] 29 | ``` 30 | 31 | **Notes:** 32 | 33 | - `1 < grid.length = grid[0].length <= 50`. 34 | - All heights `grid[i][j]` are in the range `[0, 100]`. 35 | - All buildings in `grid[i][j]` occupy the entire grid cell: that is, they are a `1 x 1 x grid[i][j]`rectangular prism. 36 | 37 | 这道题初看的时候觉得很有意思,但想不出具体什么情况下会产生这种需求。我首先想到的是生成那两个数组:从上下看的数组 和 从左右看的数组。然后依据这两个数组更新这个二维数组,这时才发现更新的规则很简单,就是选两个数组相应位置较小的值即可。最后再审一遍题发现题目的最终要求不是更新数组,而是输出这样更新之后二维数组总和比之前大了多少。总的来说这道题还是比较简单的。 38 | 39 | ## Java代码 40 | 41 | ```java 42 | class Solution { 43 | public int maxIncreaseKeepingSkyline(int[][] grid) { 44 | int result = 0; 45 | int[] topAndBottom = new int[grid[0].length]; 46 | int[] leftAndRight = new int[grid.length]; 47 | for(int i=0;ileftAndRight[i]?leftAndRight[i]:topAndBottom[j]; 56 | result += max - grid[i][j]; 57 | } 58 | } 59 | return result; 60 | } 61 | 62 | private int maxOfColumn(int[][] grid, int ColunmNums){ 63 | int max = grid[0][ColunmNums]; 64 | for(int i=0;iresult){ 41 | result = temp; 42 | } 43 | } 44 | } 45 | } 46 | } 47 | return result; 48 | } 49 | } 50 | ``` -------------------------------------------------------------------------------- /第一遍/814. Binary Tree Pruning.md: -------------------------------------------------------------------------------- 1 | ## 814. Binary Tree Pruning 2 | 3 | We are given the head node root of a binary tree, where additionally every node's value is either a 0 or a 1. 4 | 5 | Return the same tree where every subtree (of the given tree) not containing a 1 has been removed. 6 | 7 | (Recall that the subtree of a node X is X, plus every node that is a descendant of X.) 8 | 9 | **Example 1:** 10 | **Input**: [1,null,0,0,1] 11 | **Output**: [1,null,0,null,1] 12 | 13 | **Explanation:** 14 | Only the red nodes satisfy the property "every subtree not containing a 1". 15 | The diagram on the right represents the answer. 16 | 17 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/04/06/1028_2.png) 18 | 19 | **Example 2:** 20 | **Input:** [1,0,1,0,0,0,1] 21 | **Output:** [1,null,1,null,1] 22 | 23 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/04/06/1028_1.png) 24 | 25 | **Example 3:** 26 | **Input:** [1,1,0,1,1,0,1,0] 27 | **Output:** [1,1,0,1,1,null,1] 28 | 29 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/04/05/1028.png) 30 | 31 | **Note:** 32 | 33 | - The binary tree will have at most 100 nodes. 34 | - The value of each node will only be 0 or 1. 35 | 36 | [题目地址](https://leetcode.com/problems/binary-tree-pruning/) 37 | 38 | 这道题考察的应该是二叉树的遍历,核心的解法在于先将叶子0节点变为null,然后就会发现祖先节点可以用同样的方法递归的解决。 39 | 40 | ## java代码 41 | 42 | ```java 43 | /** 44 | * Definition for a binary tree node. 45 | * public class TreeNode { 46 | * int val; 47 | * TreeNode left; 48 | * TreeNode right; 49 | * TreeNode(int x) { val = x; } 50 | * } 51 | */ 52 | class Solution { 53 | public TreeNode pruneTree(TreeNode root) { 54 | if(root==null) 55 | return root; 56 | root.left = pruneTree(root.left); 57 | root.right = pruneTree(root.right); 58 | if(root.val==0 && root.left==null && root.right==null){ 59 | root=null; 60 | } 61 | return root; 62 | } 63 | } 64 | ``` -------------------------------------------------------------------------------- /第一遍/817. Linked List Components.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | We are given `head`, the head node of a linked list containing **unique integer values**. 4 | 5 | We are also given the list `G`, a subset of the values in the linked list. 6 | 7 | Return the number of connected components in `G`, where two values are connected if they appear consecutively in the linked list. 8 | 9 | **Example 1:** 10 | ``` 11 | Input: 12 | head: 0->1->2->3 13 | G = [0, 1, 3] 14 | Output: 2 15 | Explanation: 16 | 0 and 1 are connected, so [0, 1] and [3] are the two connected components. 17 | ``` 18 | 19 | **Example 2:** 20 | ``` 21 | Input: 22 | head: 0->1->2->3->4 23 | G = [0, 3, 1, 4] 24 | Output: 2 25 | Explanation: 26 | 0 and 1 are connected, 3 and 4 are connected, so [0, 1] and [3, 4] are the two connected components. 27 | ``` 28 | 29 | **Note:** 30 | 31 | - If `N` is the length of the linked list given by `head`, `1 <= N <= 10000`. 32 | - The value of each node in the linked list will be in the range `[0, N - 1]`. 33 | - `1 <= G.length <= 10000`. 34 | - `G` is a subset of all values in the linked list. 35 | 36 | [题目地址](https://leetcode.com/problems/linked-list-components/) 37 | 38 | ## 讲解 39 | 40 | 这道题目可以采用将数组转化为hashmap的方式,来消掉内存循环,从而将时间复杂度降低。另外判断连续片的个数,需要借助一个布尔型变量来记录状态。 41 | 42 | ## java代码 43 | 44 | ```java 45 | /** 46 | * Definition for singly-linked list. 47 | * public class ListNode { 48 | * int val; 49 | * ListNode next; 50 | * ListNode(int x) { val = x; } 51 | * } 52 | */ 53 | class Solution { 54 | public int numComponents(ListNode head, int[] G) { 55 | ListNode index = head; 56 | Set set = new HashSet<>(); 57 | for(int i=0;i index = new ArrayList<>(); 33 | for(int i=0;iindex.get(count)){ 49 | result[i] = i - index.get(count); 50 | }else if(count>0){ 51 | if(i-index.get(count-1) < index.get(count)-i){ 52 | result[i] = i-index.get(count-1); 53 | }else{ 54 | result[i] = index.get(count)-i; 55 | } 56 | } 57 | } 58 | return result; 59 | } 60 | } 61 | ``` -------------------------------------------------------------------------------- /第一遍/824. Goat Latin.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | A sentence `S` is given, composed of words separated by spaces. Each word consists of lowercase and uppercase letters only. 4 | 5 | We would like to convert the sentence to "Goat Latin" (a made-up language similar to Pig Latin.) 6 | 7 | The rules of Goat Latin are as follows: 8 | 9 | If a word begins with a vowel (a, e, i, o, or u), append `"ma"` to the end of the word. 10 | For example, the word 'apple' becomes 'applema'. 11 | 12 | If a word begins with a consonant (i.e. not a vowel), remove the first letter and append it to the end, then add `"ma"`. 13 | For example, the word `"goat"` becomes `"oatgma"`. 14 | 15 | Add one letter `'a'` to the end of each word per its word index in the sentence, starting with 1. 16 | For example, the first word gets `"a"` added to the end, the second word gets `"aa"` added to the end and so on. 17 | Return the final sentence representing the conversion from `S` to Goat Latin. 18 | 19 | **Example 1:** 20 | ``` 21 | Input: "I speak Goat Latin" 22 | Output: "Imaa peaksmaaa oatGmaaaa atinLmaaaaa" 23 | ``` 24 | 25 | **Example 2:** 26 | ``` 27 | Input: "The quick brown fox jumped over the lazy dog" 28 | Output: "heTmaa uickqmaaa rownbmaaaa oxfmaaaaa umpedjmaaaaaa overmaaaaaaa hetmaaaaaaaa azylmaaaaaaaaa ogdmaaaaaaaaaa" 29 | ``` 30 | 31 | **Notes:** 32 | 33 | - `S` contains only uppercase, lowercase and spaces. Exactly one space between each word. 34 | - `1 <= S.length <= 150`. 35 | 36 | [题目地址](https://leetcode.com/problems/goat-latin/) 37 | 38 | ## 讲解 39 | 40 | 这个题目看着挺简单的,但用代码写出来还挺长的。 41 | 42 | ## java代码 43 | 44 | ```java 45 | class Solution { 46 | public String toGoatLatin(String S) { 47 | StringBuilder sb = new StringBuilder(); 48 | StringBuilder a = new StringBuilder(); 49 | char[] vowel = {'a', 'e', 'i', 'o', 'u'}; 50 | int wordCount = 1; 51 | for(int i=0;i> rooms) { 50 | Set set = new HashSet(); 51 | Queue queue = new LinkedList<>(); 52 | for(Integer x:rooms.get(0)){ 53 | queue.offer(x); 54 | } 55 | while(!queue.isEmpty()){ 56 | int room = queue.poll(); 57 | if(set.contains(room)){ 58 | continue; 59 | }else{ 60 | set.add(room); 61 | List list = rooms.get(room); 62 | if(list!=null && list.size()>0){ 63 | for(Integer x: list){ 64 | queue.offer(x); 65 | } 66 | } 67 | } 68 | } 69 | for(int i=1;i= 3` 6 | There exists some `0 < i < A.length - 1` such that `A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]` 7 | Given an array that is definitely a mountain, return any `i` such that `A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]`. 8 | 9 | **Example 1:** 10 | ``` 11 | Input: [0,1,0] 12 | Output: 1 13 | ``` 14 | 15 | **Example 2:** 16 | ``` 17 | Input: [0,2,1,0] 18 | Output: 1 19 | ``` 20 | 21 | **Note:** 22 | 23 | 1. `3 <= A.length <= 10000` 24 | 2. `0 <= A[i] <= 10^6` 25 | 3. A is a mountain, as defined above. 26 | 27 | 这题非常简单,就是求数组中的最大值 28 | 29 | ## java代码 30 | 31 | ```java 32 | class Solution { 33 | public int peakIndexInMountainArray(int[] A) { 34 | int max = A[0]; 35 | for(int i=1;iA[i]){ 37 | return i-1; 38 | }else{ 39 | max=A[i]; 40 | } 41 | } 42 | return 0; 43 | } 44 | } 45 | ``` -------------------------------------------------------------------------------- /第一遍/856. Score of Parentheses.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a balanced parentheses string `S`, compute the score of the string based on the following rule: 4 | 5 | `()` has score 1 6 | `AB` has score `A + B`, where A and B are balanced parentheses strings. 7 | `(A)` has score `2 * A`, where A is a balanced parentheses string. 8 | 9 | **Example 1:** 10 | ``` 11 | Input: "()" 12 | Output: 1 13 | ``` 14 | 15 | **Example 2:** 16 | ``` 17 | Input: "(())" 18 | Output: 2 19 | ``` 20 | 21 | **Example 3:** 22 | ``` 23 | Input: "()()" 24 | Output: 2 25 | ``` 26 | 27 | **Example 4:** 28 | ``` 29 | Input: "(()(()))" 30 | Output: 6 31 | ``` 32 | 33 | **Note:** 34 | 35 | 1. `S` is a balanced parentheses string, containing only `(` and `)`. 36 | 2. `2 <= S.length <= 50` 37 | 38 | [题目地址](https://leetcode.com/problems/score-of-parentheses/) 39 | 40 | ## 讲解 41 | 42 | 这道题分类都有点难,可以算在智力题里面。主要是要理解一个套路: 43 | 44 | ``` 45 | "(()(()))" -> "(())" + "((()))" = 2 + 4 46 | ``` 47 | 48 | 这样就会发现,可以维护一个层数变量,然后遍历的时候,遇到`'('`就加一,遇到")"就减一,遇到`"()"`这一对,就相当于找到了一组。然后把找到的所有组相加就行了。 49 | 50 | ## java代码 51 | 52 | ```java 53 | class Solution { 54 | public int scoreOfParentheses(String S) { 55 | int d = -1; 56 | int result = 0; 57 | for(int i=0;iA.length/2){ 94 | flipColumn(A, columnNum); 95 | } 96 | } 97 | } 98 | ``` 99 | 100 | ## 变种 101 | 102 | 跟朋友讨论这个题目的时候,他也看错了题,他看成要同时翻转某个元素所在的行和列。那么这么一来题目就变复杂了很多。 103 | 104 | 首先还是依据一个性质:首位权重最大,所以我们尝试让第一列全1: 105 | 106 | ![978C53E5-CC43-4D63-A566-4670472CEE96.png](https://i.loli.net/2018/12/25/5c223cda1acaa.png) 107 | 108 | 哪些情况是翻不出全1的呢? 109 | -------------------------------------------------------------------------------- /第一遍/865. Smallest Subtree with all the Deepest Nodes.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a binary tree rooted at `root`, the depth of each node is the shortest distance to the root. 4 | 5 | A node is deepest if it has the largest depth possible among any node in the entire tree. 6 | 7 | The subtree of a node is that node, plus the set of all descendants of that node. 8 | 9 | Return the node with the largest depth such that it contains all the deepest nodes in its subtree. 10 | 11 | **Example 1:** 12 | ``` 13 | Input: [3,5,1,6,2,0,8,null,null,7,4] 14 | Output: [2,7,4] 15 | Explanation: 16 | ``` 17 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/07/01/sketch1.png) 18 | ``` 19 | We return the node with value 2, colored in yellow in the diagram. 20 | The nodes colored in blue are the deepest nodes of the tree. 21 | The input "[3, 5, 1, 6, 2, 0, 8, null, null, 7, 4]" is a serialization of the given tree. 22 | The output "[2, 7, 4]" is a serialization of the subtree rooted at the node with value 2. 23 | Both the input and output have TreeNode type. 24 | ``` 25 | 26 | **Note:** 27 | 28 | - The number of nodes in the tree will be between 1 and 500. 29 | - The values of each node are unique. 30 | 31 | [题目地址](https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/) 32 | 33 | ## 讲解 34 | 35 | 这道题是一道典型的分治递归题,分治和递归的核心思想是把问题规模缩小。从根节点开始判断,左右子树是否深度相同,若相同则我们要返回根节点,若不同,就返回深度大的那个子树返回来的结点。 36 | 37 | ## java代码 38 | 39 | ```java 40 | /** 41 | * Definition for a binary tree node. 42 | * public class TreeNode { 43 | * int val; 44 | * TreeNode left; 45 | * TreeNode right; 46 | * TreeNode(int x) { val = x; } 47 | * } 48 | */ 49 | class Solution { 50 | public TreeNode subtreeWithAllDeepest(TreeNode root) { 51 | return searchTree(root).treeNode; 52 | } 53 | 54 | private TreeNodeWithDepth searchTree(TreeNode root){ 55 | if(root==null){ 56 | return null; 57 | } 58 | TreeNodeWithDepth node1=null; 59 | TreeNodeWithDepth node2 = null; 60 | if(root.left!=null){ 61 | node1 = searchTree(root.left); 62 | } 63 | if(root.right!=null){ 64 | node2 = searchTree(root.right); 65 | } 66 | TreeNodeWithDepth now = new TreeNodeWithDepth(root); 67 | if(node1!=null && node2!=null){ 68 | if(node1.depth==node2.depth){ 69 | now.depth=node1.depth+1; 70 | now.treeNode = root; 71 | }else if(node1.depth0){ 68 | if(temp%2==1){ 69 | if(index==1){ 70 | count++; 71 | max = max>= 1; 83 | 84 | } 85 | return max; 86 | } 87 | } 88 | ``` -------------------------------------------------------------------------------- /第一遍/872. Leaf-Similar Trees.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Consider all the leaves of a binary tree. From left to right order, the values of those leaves form a leaf value sequence. 4 | 5 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/07/16/tree.png) 6 | 7 | For example, in the given tree above, the leaf value sequence is `(6, 7, 4, 9, 8)`. 8 | 9 | Two binary trees are considered leaf-similar if their leaf value sequence is the same. 10 | 11 | Return `true` if and only if the two given trees with head nodes `root1` and `root2` are leaf-similar. 12 | 13 | 14 | 15 | **Note:** 16 | 17 | - Both of the given trees will have between `1` and `100` nodes. 18 | 19 | ## 讲解 20 | 21 | 这道题的思路很简单,先扫描出两个树的叶子结果集,然后比较就行了。考察点是树的遍历。递归的时候首先要判断结点是否为空。 22 | 23 | ## Java代码 24 | 25 | ```java 26 | /** 27 | * Definition for a binary tree node. 28 | * public class TreeNode { 29 | * int val; 30 | * TreeNode left; 31 | * TreeNode right; 32 | * TreeNode(int x) { val = x; } 33 | * } 34 | */ 35 | class Solution { 36 | public boolean leafSimilar(TreeNode root1, TreeNode root2) { 37 | List leaves1 = new ArrayList<>(); 38 | List leaves2 = new ArrayList<>(); 39 | getLeaves(root1, leaves1); 40 | getLeaves(root2, leaves2); 41 | if(leaves1.size()!=leaves2.size()){ 42 | return false; 43 | }else{ 44 | for(int i=0;i leaves){ 54 | if(root==null){ 55 | return; 56 | } 57 | if(root.left==null && root.right==null){ 58 | leaves.add(root.val); 59 | return; 60 | } 61 | getLeaves(root.left, leaves); 62 | getLeaves(root.right, leaves); 63 | } 64 | } 65 | ``` -------------------------------------------------------------------------------- /第一遍/876. Middle of the Linked List.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a non-empty, singly linked list with head node `head`, return a middle node of linked list. 4 | 5 | If there are two middle nodes, return the second middle node. 6 | 7 | **Example 1:** 8 | ``` 9 | Input: [1,2,3,4,5] 10 | Output: Node 3 from this list (Serialization: [3,4,5]) 11 | The returned node has value 3. (The judge's serialization of this node is [3,4,5]). 12 | Note that we returned a ListNode object ans, such that: 13 | ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL. 14 | ``` 15 | 16 | **Example 2:** 17 | ``` 18 | Input: [1,2,3,4,5,6] 19 | Output: Node 4 from this list (Serialization: [4,5,6]) 20 | Since the list has two middle nodes with values 3 and 4, we return the second one. 21 | ``` 22 | 23 | **Note:** 24 | 25 | - The number of nodes in the given list will be between `1` and `100`. 26 | 27 | [题目地址](https://leetcode.com/problems/middle-of-the-linked-list/) 28 | 29 | ## 讲解 30 | 31 | 一看到这个题目我就知道用快慢指针。但具体操作的时候有些细节需要注意,要让快慢指针指向第0个位置,而不是head(head算作第一个位置)。 32 | 33 | ## Java代码 34 | 35 | ```java 36 | /** 37 | * Definition for singly-linked list. 38 | * public class ListNode { 39 | * int val; 40 | * ListNode next; 41 | * ListNode(int x) { val = x; } 42 | * } 43 | */ 44 | class Solution { 45 | public ListNode middleNode(ListNode head) { 46 | System.out.println(head.val); 47 | ListNode slow = new ListNode(0); 48 | ListNode fast = new ListNode(0); 49 | slow.next = head; 50 | fast.next = head; 51 | while(slow!=null && fast!=null){ 52 | slow = slow.next; 53 | if(fast.next!=null){ 54 | fast = fast.next.next; 55 | }else{ 56 | fast = fast.next; 57 | } 58 | } 59 | return slow; 60 | } 61 | } 62 | ``` -------------------------------------------------------------------------------- /第一遍/877. Stone Game.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Alex and Lee play a game with piles of stones. There are an even number of piles **arranged in a row**, and each pile has a positive integer number of stones `piles[i]`. 4 | 5 | The objective of the game is to end with the most stones. The total number of stones is odd, so there are no ties. 6 | 7 | Alex and Lee take turns, with Alex starting first. Each turn, a player takes the entire pile of stones from either the beginning or the end of the row. This continues until there are no more piles left, at which point the person with the most stones wins. 8 | 9 | Assuming Alex and Lee play optimally, return `True` if and only if Alex wins the game. 10 | 11 | **Example 1:** 12 | ``` 13 | Input: [5,3,4,5] 14 | Output: true 15 | Explanation: 16 | Alex starts first, and can only take the first 5 or the last 5. 17 | Say he takes the first 5, so that the row becomes [3, 4, 5]. 18 | If Lee takes 3, then the board is [4, 5], and Alex takes 5 to win with 10 points. 19 | If Lee takes the last 5, then the board is [3, 4], and Alex takes 4 to win with 9 points. 20 | This demonstrated that taking the first 5 was a winning move for Alex, so we return true. 21 | ``` 22 | 23 | **Note:** 24 | 25 | 1. `2 <= piles.length <= 500` 26 | 2. `piles.length` is even. 27 | 3. `1 <= piles[i] <= 500` 28 | 4. `sum(piles)` is odd. 29 | 30 | [题目地址](https://leetcode.com/problems/stone-game/) 31 | 32 | ## 讲解 33 | 34 | 动态规划,好久没做动态规划了。三要素:最优子结构、无后效性、子问题重叠。核心思想是记录子问题的解(空间换时间)。具体做法有 **自底向上(迭代,规模由小到大)**,**自顶向下(递归,规模由大到小)**。 35 | 36 | ## Java代码 37 | 38 | 自顶向下: 39 | 40 | 递归的比较好理解一点,状态转移方程:`f(n) = {拿左边+f(n-1)左, 拿右边+f(n-1)右}` 41 | 42 | ```java 43 | class Solution { 44 | int beginIndex; 45 | int endIndex; 46 | int[][] dp; 47 | public boolean stoneGame(int[] piles) { 48 | beginIndex = 0; 49 | endIndex = piles.length-1; 50 | dp = new int[piles.length][piles.length]; 51 | for(int i=0;isum/2?true:false; 61 | } 62 | 63 | private int stoneGame(int[] piles, int begin, int end){ 64 | if(begin>=end){ 65 | return 0; 66 | } 67 | if(dp[begin][end]!=-1){ 68 | return dp[begin][end]; 69 | }else{ 70 | dp[begin][end] = Math.max(piles[begin]+stoneGame(piles, begin+1, end), piles[end]+stoneGame(piles, begin, end-1)); 71 | return dp[begin][end]; 72 | } 73 | } 74 | } 75 | ``` 76 | 77 | 自底向上: 78 | 79 | 1. 把另一个人拿的数当做减。 80 | 2. 求piles[i]到piles[j]的最优解,并存起来。 81 | 82 | ```java 83 | class Solution { 84 | public boolean stoneGame(int[] piles) { 85 | int[][] dp = new int[piles.length][piles.length]; 86 | for(int i=0;i0; 97 | } 98 | } 99 | ``` -------------------------------------------------------------------------------- /第一遍/883. Projection Area of 3D Shapes.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | On a `N * N` grid, we place some `1 * 1 * 1` cubes that are axis-aligned with the x, y, and z axes. 4 | 5 | Each value `v = grid[i][j]` represents a tower of v cubes placed on top of grid cell `(i, j)`. 6 | 7 | Now we view the projection of these cubes onto the xy, yz, and zx planes. 8 | 9 | A projection is like a shadow, that maps our 3 dimensional figure to a 2 dimensional plane. 10 | 11 | Here, we are viewing the "shadow" when looking at the cubes from the top, the front, and the side. 12 | 13 | Return the total area of all three projections. 14 | 15 | 16 | 17 | **Example 1:** 18 | ``` 19 | Input: [[2]] 20 | Output: 5 21 | ``` 22 | 23 | **Example 2:** 24 | ``` 25 | Input: [[1,2],[3,4]] 26 | Output: 17 27 | ``` 28 | 29 | **Explanation:** 30 | ``` 31 | Here are the three projections ("shadows") of the shape made with each axis-aligned plane. 32 | ``` 33 | ![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/08/02/shadow.png) 34 | 35 | **Example 3:** 36 | ``` 37 | Input: [[1,0],[0,2]] 38 | Output: 8 39 | ``` 40 | 41 | **Example 4:** 42 | ``` 43 | Input: [[1,1,1],[1,0,1],[1,1,1]] 44 | Output: 14 45 | ``` 46 | 47 | **Example 5:** 48 | ``` 49 | Input: [[2,2,2],[2,1,2],[2,2,2]] 50 | Output: 21 51 | ``` 52 | 53 | **Note:** 54 | 55 | - `1 <= grid.length = grid[0].length <= 50` 56 | - `0 <= grid[i][j] <= 50` 57 | 58 | [题目地址](https://leetcode.com/problems/projection-area-of-3d-shapes/) 59 | 60 | ## 讲解 61 | 62 | 这题其实很简单,就是考察对数组的横纵操作。 63 | 64 | ## Java代码 65 | 66 | ```java 67 | class Solution { 68 | public int projectionArea(int[][] grid) { 69 | return countRow(grid)+countColumn(grid)+countPlan(grid); 70 | } 71 | 72 | private int countRow(int[][] grid){ 73 | int result = 0; 74 | for(int i=0;i0){ 105 | result++; 106 | } 107 | } 108 | } 109 | return result; 110 | } 111 | } 112 | ``` -------------------------------------------------------------------------------- /第一遍/884. Uncommon Words from Two Sentences.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | We are given two sentences `A` and `B`. (A sentence is a string of space separated words. Each word consists only of lowercase letters.) 4 | 5 | A word is uncommon if it appears exactly once in one of the sentences, and does not appear in the other sentence. 6 | 7 | Return a list of all uncommon words. 8 | 9 | You may return the list in any order. 10 | 11 | 12 | 13 | **Example 1:** 14 | ``` 15 | Input: A = "this apple is sweet", B = "this apple is sour" 16 | Output: ["sweet","sour"] 17 | ``` 18 | 19 | **Example 2:** 20 | ``` 21 | Input: A = "apple apple", B = "banana" 22 | Output: ["banana"] 23 | ``` 24 | 25 | **Note:** 26 | 27 | 1. `0 <= A.length <= 200` 28 | 2. `0 <= B.length <= 200` 29 | 3. `A` and `B` both contain only spaces and lowercase letters. 30 | 31 | [题目地址](https://leetcode.com/problems/uncommon-words-from-two-sentences/) 32 | 33 | ## 讲解 34 | 35 | 用hashmap记录每一个单词 36 | 37 | ## Java代码 38 | 39 | ```java 40 | class Solution { 41 | private Map map = new HashMap<>(); 42 | public String[] uncommonFromSentences(String A, String B) { 43 | List result = new ArrayList<>(); 44 | countString(A); 45 | countString(B); 46 | for(String key:map.keySet()){ 47 | if(map.get(key)==1){ 48 | result.add(key); 49 | } 50 | } 51 | String[] str = new String[result.size()]; 52 | return result.toArray(str); 53 | } 54 | 55 | private void countString(String A){ 56 | int index=0; 57 | for(int i=0;i=0 && c0>=0 && r0=0 && c0>=0 && r0=0 && c0>=0 && r0=0 && c0>=0 && r0sumB: 70 | if i-(sumA-mid) in setB: 71 | return [i, i-(sumA-mid)] 72 | else: 73 | if i+(mid-sumA) in setB: 74 | return [i, i+(mid-sumA)] 75 | ``` -------------------------------------------------------------------------------- /第一遍/889. Construct Binary Tree from Preorder and Postorder Traversal.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Return any binary tree that matches the given preorder and postorder traversals. 4 | 5 | Values in the traversals pre and post are distinct positive integers. 6 | 7 | 8 | 9 | **Example 1:** 10 | ``` 11 | Input: pre = [1,2,4,5,3,6,7], post = [4,5,2,6,7,3,1] 12 | Output: [1,2,3,4,5,6,7] 13 | ``` 14 | 15 | **Note:** 16 | 17 | - `1 <= pre.length == post.length <= 30` 18 | - `pre[]` and `post[]` are both permutations of `1, 2, ..., pre.length`. 19 | - It is guaranteed an answer exists. If there exists multiple answers, you can return any of them. 20 | 21 | ## 讲解 22 | 23 | 先序遍历和后序遍历无法确定一颗二叉树,所以这里有可能返回多种不同的树,但只要是正确的就行。 24 | 25 | 解这道题的关键在于分割左右子树,先序遍历中紧跟根节点后的也有可能不是左子树,但如果是这样的话,后续遍历中也不会有左子树,那么右子树的根节点就会在两种遍历中都挨着总根节点。所以思路就出来了,我们在先序遍历中拿到根节点后面的那个节点,然后在后序遍历中找到这个节点,这个点就在后序遍历中分割出了左右子树。 26 | 27 | 递归之。 28 | 29 | ## Java代码 30 | 31 | ```java 32 | /** 33 | * Definition for a binary tree node. 34 | * public class TreeNode { 35 | * int val; 36 | * TreeNode left; 37 | * TreeNode right; 38 | * TreeNode(int x) { val = x; } 39 | * } 40 | */ 41 | class Solution { 42 | public TreeNode constructFromPrePost(int[] pre, int[] post) { 43 | return constructFromPrePost(pre, 0, pre.length-1, post, 0, post.length-1); 44 | } 45 | 46 | private TreeNode constructFromPrePost(int[] pre, int preLeft, int preRight, int[] post, int postLeft, int postRight){ 47 | if(preLeft>preRight || postLeft>postRight){ 48 | return null; 49 | }else if(preLeft==preRight){ 50 | return new TreeNode(pre[preLeft]); 51 | } 52 | TreeNode root = new TreeNode(pre[preLeft]); 53 | for(int i=postRight-1;i>=postLeft;i--){ 54 | if(post[i]==pre[preLeft+1]){ 55 | root.left = constructFromPrePost(pre, preLeft+1, preLeft+1+i-postLeft, post, postLeft, i); 56 | root.right = constructFromPrePost(pre, preLeft+2+i-postLeft, preRight, post, i+1, postRight-1); 57 | } 58 | } 59 | return root; 60 | } 61 | } 62 | ``` -------------------------------------------------------------------------------- /第一遍/890. Find and Replace Pattern.md: -------------------------------------------------------------------------------- 1 | ## 890. Find and Replace Pattern 2 | 3 | You have a list of `words` and a `pattern`, and you want to know which `words` in words matches the pattern. 4 | 5 | A word matches the pattern if there exists a permutation of letters `p` so that after replacing every letter x in the pattern with `p(x)`, we get the desired word. 6 | 7 | (Recall that a permutation of letters is a bijection from letters to letters: every letter maps to another letter, and no two letters map to the same letter.) 8 | 9 | Return a list of the `words` in words that match the given pattern. 10 | 11 | You may return the answer in any order. 12 | 13 | **Example 1:** 14 | 15 | ``` 16 | Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb" 17 | Output: ["mee","aqq"] 18 | Explanation: "mee" matches the pattern because there is a permutation {a -> m, b -> e, ...}. 19 | "ccc" does not match the pattern because {a -> c, b -> c, ...} is not a permutation, 20 | since a and b map to the same letter. 21 | ``` 22 | 23 | **Note:** 24 | 25 | - `1 <= words.length <= 50` 26 | - `1 <= pattern.length = words[i].length <= 20` 27 | 28 | [题目地址](https://leetcode.com/problems/find-and-replace-pattern/) 29 | 30 | 这个题的难点在于两个字母的一一对应关系,显然map只能做到单向的映射,我的做法是使用两个map。 31 | 32 | ## java 代码 33 | 34 | ```java 35 | class Solution { 36 | public List findAndReplacePattern(String[] words, String pattern) { 37 | List result = new ArrayList<>(); 38 | for(String s:words){ 39 | char[] w = s.toCharArray(); 40 | char[] p = pattern.toCharArray(); 41 | Map map1 = new HashMap<>(); 42 | Map map2 = new HashMap<>(); 43 | for(int i=0;i set = new HashSet<>(); 60 | for(String s:A){ 61 | char[] c = s.toCharArray(); 62 | List temp1 = new ArrayList<>(); 63 | if(c.length>2){ 64 | List temp2 = new ArrayList<>(); 65 | for(int i=0;i allPossibleFBT(int N) { 42 | List result = new ArrayList<>(); 43 | if(N%2==0){ 44 | return result; 45 | } 46 | if(N==1){ 47 | result.add(new TreeNode(0)); 48 | return result; 49 | } 50 | for(int i=1;i= A[j]`. 6 | 7 | Return `true` if and only if the given array `A` is monotonic. 8 | 9 | **Example 1:** 10 | ``` 11 | Input: [1,2,2,3] 12 | Output: true 13 | ``` 14 | 15 | **Example 2:** 16 | ``` 17 | Input: [6,5,4,4] 18 | Output: true 19 | ``` 20 | 21 | **Example 3:** 22 | ``` 23 | Input: [1,3,2] 24 | Output: false 25 | ``` 26 | 27 | **Example 4:** 28 | ``` 29 | Input: [1,2,4,5] 30 | Output: true 31 | ``` 32 | 33 | **Example 5:** 34 | ``` 35 | Input: [1,1,1] 36 | Output: true 37 | ``` 38 | 39 | **Note:** 40 | 41 | 1. `1 <= A.length <= 50000` 42 | 2. `-100000 <= A[i] <= 100000` 43 | 44 | [题目地址](https://leetcode.com/problems/monotonic-array/) 45 | 46 | ## 讲解 47 | 48 | 这个题目看起来挺简单,里面的逻辑其实有点多。代码看起来不怎么清爽 49 | 50 | ## python代码 51 | 52 | ```python 53 | class Solution: 54 | def isMonotonic(self, A): 55 | """ 56 | :type A: List[int] 57 | :rtype: bool 58 | """ 59 | if len(A)==1: 60 | return True 61 | i=1 62 | increasingFlag = True 63 | while iA[i-1]: 73 | return False 74 | i += 1 75 | return True 76 | ``` -------------------------------------------------------------------------------- /第一遍/897. Increasing Order Search Tree.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a tree, rearrange the tree in **in-order** so that the leftmost node in the tree is now the root of the tree, and every node has no left child and only 1 right child. 4 | 5 | ``` 6 | Example 1: 7 | Input: [5,3,6,2,4,null,8,1,null,null,null,7,9] 8 | 9 | 5 10 | / \ 11 | 3 6 12 | / \ \ 13 | 2 4 8 14 | / / \ 15 | 1 7 9 16 | 17 | Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9] 18 | 19 | 1 20 | \ 21 | 2 22 | \ 23 | 3 24 | \ 25 | 4 26 | \ 27 | 5 28 | \ 29 | 6 30 | \ 31 | 7 32 | \ 33 | 8 34 | \ 35 | 9 36 | ``` 37 | 38 | **Note:** 39 | 40 | 1. The number of nodes in the given tree will be between 1 and 100. 41 | 2. Each node will have a unique integer value from 0 to 1000. 42 | 43 | [题目地址](https://leetcode.com/problems/increasing-order-search-tree/) 44 | 45 | ## 讲解 46 | 47 | 这道题讲道理本来应该是很简单的,但我犯了一个很愚蠢的错误,就是直接使用原来的树的结点,这样原来的树的结构也被带过来了,导致形成了死递归。其实我只需要原来的结点的值。`temp.right = new TreeNode(root.val);`而不是:`temp.right = root;` 48 | 49 | ## Java代码 50 | 51 | ```java 52 | /** 53 | * Definition for a binary tree node. 54 | * public class TreeNode { 55 | * int val; 56 | * TreeNode left; 57 | * TreeNode right; 58 | * TreeNode(int x) { val = x; } 59 | * } 60 | */ 61 | class Solution { 62 | TreeNode result = new TreeNode(0); 63 | TreeNode temp = result; 64 | public TreeNode increasingBST(TreeNode root) { 65 | if(root==null){ 66 | return root; 67 | } 68 | if(root.left!=null){ 69 | increasingBST(root.left); 70 | } 71 | temp.right = new TreeNode(root.val); 72 | temp = temp.right; 73 | if(root.right!=null){ 74 | increasingBST(root.right); 75 | } 76 | return result.right; 77 | } 78 | } 79 | ``` -------------------------------------------------------------------------------- /第一遍/905. Sort Array By Parity.md: -------------------------------------------------------------------------------- 1 | ## 905. Sort Array By Parity 2 | 3 | Given an array A of non-negative integers, return an array consisting of all the even elements of A, followed by all the odd elements of A. 4 | 5 | You may return any answer array that satisfies this condition. 6 | 7 | **Example 1:** 8 | 9 | ``` 10 | Input: [3,1,2,4] 11 | Output: [2,4,3,1] 12 | The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted. 13 | ``` 14 | 15 | **Note:** 16 | 17 | 1. `1 <= A.length <= 5000` 18 | 2. `0 <= A[i] <= 5000` 19 | 20 | [题目地址](https://leetcode.com/problems/sort-array-by-parity/) 21 | 22 | 这题相当简单,我用了一个额外的数组来存储结果,使用两个指针,一个从前往后,指明插入偶数的位置,一个从后往前,指明奇数插入的位置。 23 | 24 | ## java代码 25 | 26 | ```java 27 | class Solution { 28 | public int[] sortArrayByParity(int[] A) { 29 | int[] result = new int[A.length]; 30 | int i=0; 31 | int j=A.length-1; 32 | for(int x:A){ 33 | if(x%2==0){ 34 | result[i++]=x; 35 | }else{ 36 | result[j--]=x; 37 | } 38 | } 39 | return result; 40 | } 41 | } 42 | ``` -------------------------------------------------------------------------------- /第一遍/908. Smallest Range I.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given an array `A` of integers, for each integer `A[i]` we may choose any `x` with `-K <= x <= K`, and add `x` to `A[i]`. 4 | 5 | After this process, we have some array `B`. 6 | 7 | Return the smallest possible difference between the maximum value of `B` and the minimum value of `B`. 8 | 9 | 10 | **Example 1:** 11 | ``` 12 | Input: A = [1], K = 0 13 | Output: 0 14 | Explanation: B = [1] 15 | ``` 16 | 17 | **Example 2:** 18 | ``` 19 | Input: A = [0,10], K = 2 20 | Output: 6 21 | Explanation: B = [2,8] 22 | ``` 23 | 24 | **Example 3:** 25 | ``` 26 | Input: A = [1,3,6], K = 3 27 | Output: 0 28 | Explanation: B = [3,3,3] or B = [4,4,4] 29 | ``` 30 | 31 | **Note:** 32 | 33 | 1. `1 <= A.length <= 10000` 34 | 2. `0 <= A[i] <= 10000` 35 | 3. `0 <= K <= 10000` 36 | 37 | [题目地址](https://leetcode.com/problems/smallest-range-i/) 38 | 39 | ## 讲解 40 | 41 | 这道题刚开始一直没看懂题,但是看懂了之后就会发现非常非常简单。题目的意思是对一个数组A中的每一个数,都加一个x,x的取值范围是`-K <= x <= K`,然后得到结果数组B,取B中的最大值和最小值,让这两者的差最小(最小是0),求这个最小值。 42 | 43 | 这里有个误区是所有数加的x都相同,但你仔细看题目给的例子,x并不是要相同的。 44 | 45 | 看完例子我们发现,只要A的最大和最小值之差小于2倍K,我们就能让B中的元素全部相等。这就是解题思路。 46 | 47 | ## Java代码 48 | 49 | ```java 50 | class Solution { 51 | public int smallestRangeI(int[] A, int K) { 52 | int max=A[0]; 53 | int min=A[0]; 54 | for(int i=0;iA[i]){ 59 | min=A[i]; 60 | } 61 | } 62 | if(2*K>max-min){ 63 | return 0; 64 | }else{ 65 | return max-min-2*K; 66 | } 67 | } 68 | } 69 | ``` 70 | -------------------------------------------------------------------------------- /第一遍/917. Reverse Only Letters.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given a string `S`, return the "reversed" string where all characters that are not a letter stay in the same place, and all letters reverse their positions. 4 | 5 | **Example 1:** 6 | ``` 7 | Input: "ab-cd" 8 | Output: "dc-ba" 9 | ``` 10 | 11 | **Example 2:** 12 | ``` 13 | Input: "a-bC-dEf-ghIj" 14 | Output: "j-Ih-gfE-dCba" 15 | ``` 16 | 17 | **Example 3:** 18 | ``` 19 | Input: "Test1ng-Leet=code-Q!" 20 | Output: "Qedo1ct-eeLg=ntse-T!" 21 | ``` 22 | 23 | **Note:** 24 | 25 | 1. `S.length <= 100` 26 | 2. `33 <= S[i].ASCIIcode <= 122` 27 | 3. `S` doesn't contain `\` or `"` 28 | 29 | ## 讲解 30 | 31 | 字符串操作,将字母reverse,其他字符保持在原来位置上。我使用了两个数组,一个指针 32 | 33 | ## java代码 34 | 35 | ```java 36 | class Solution { 37 | public String reverseOnlyLetters(String S) { 38 | char[] c = S.toCharArray(); 39 | char[] result = S.toCharArray(); 40 | int index = result.length-1; 41 | for(int i=0;i='a' && c[i]<='z' || c[i]>='A' && c[i]<='Z'){ 43 | while(index>=0 && !(result[index]>='a' && result[index]<='z' || result[index]>='A' && result[index]<='Z')){ 44 | index--; 45 | } 46 | if(index>=0) 47 | result[index--] = c[i]; 48 | } 49 | } 50 | return String.valueOf(result); 51 | } 52 | } 53 | ``` -------------------------------------------------------------------------------- /第一遍/921. Minimum Add to Make Parentheses Valid.md: -------------------------------------------------------------------------------- 1 | ## 921. Minimum Add to Make Parentheses Valid 2 | 3 | Given a string `S` of `'('` and `')'` parentheses, we add the minimum number of parentheses ( `'('` or `')'`, and in any positions ) so that the resulting parentheses string is valid. 4 | 5 | Formally, a parentheses string is valid if and only if: 6 | 7 | It is the empty string, or 8 | It can be written as `AB` (`A` concatenated with `B`), where A and B are valid strings, or 9 | It can be written as (`A`), where `A` is a valid string. 10 | Given a parentheses string, return the minimum number of parentheses we must add to make the resulting string valid. 11 | 12 | **Example 1:** 13 | ``` 14 | Input: "())" 15 | Output: 1 16 | ``` 17 | 18 | **Example 2:** 19 | ``` 20 | Input: "(((" 21 | Output: 3 22 | ``` 23 | 24 | **Example 3:** 25 | ``` 26 | Input: "()" 27 | Output: 0 28 | ``` 29 | 30 | **Example 4:** 31 | ``` 32 | Input: "()))((" 33 | Output: 4 34 | ``` 35 | 36 | **Note:** 37 | 38 | - `S.length <= 1000` 39 | - `S` only consists of `'('` and `')'` characters. 40 | 41 | [题目地址](https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/) 42 | 43 | 这是栈的经典应用 44 | 45 | ## java代码 46 | 47 | ```java 48 | class Solution { 49 | public int minAddToMakeValid(String S) { 50 | Stack stack = new Stack<>(); 51 | char[] c = S.toCharArray(); 52 | for(int i=0;i set = new HashSet<>(); 39 | for(String s:emails){ 40 | int indexOfAt = s.indexOf("@"); 41 | StringBuilder stringBuilder = new StringBuilder(); 42 | Boolean flag = false; 43 | for(int i=0;i queue; 37 | 38 | public RecentCounter() { 39 | queue = new LinkedList<>(); 40 | } 41 | 42 | public int ping(int t) { 43 | while(queue.size()>0 && queue.peek()=L && root.val<=R){ 50 | result += root.val; 51 | } 52 | rangeSumBST(root.left, L, R); 53 | rangeSumBST(root.right, L, R); 54 | return result; 55 | } 56 | } 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /第一遍/942. DI String Match.md: -------------------------------------------------------------------------------- 1 | ## 942. DI String Match 2 | 3 | Given a string `S` that **only** contains "I" (increase) or "D" (decrease), let `N = S.length`. 4 | 5 | Return **any** permutation `A` of `[0, 1, ..., N]` such that for all `i = 0, ..., N-1`: 6 | 7 | - If `S[i] == "I"`, then `A[i] < A[i+1]` 8 | - If `S[i] == "D"`, then `A[i] > A[i+1]` 9 | 10 | 11 | **Example 1:** 12 | ``` 13 | Input: "IDID" 14 | Output: [0,4,1,3,2] 15 | ``` 16 | 17 | Example 2: 18 | ``` 19 | Input: "III" 20 | Output: [0,1,2,3] 21 | ``` 22 | 23 | Example 3: 24 | ``` 25 | Input: "DDI" 26 | Output: [3,2,0,1] 27 | ``` 28 | 29 | **Note:** 30 | 31 | 1. `1 <= S.length <= 10000` 32 | 2. `S` only contains characters `"I"` or `"D"`. 33 | 34 | [题目地址](https://leetcode.com/problems/di-string-match/) 35 | 36 | 算法:默认是递增的,然后根据D修改顺序,每遇到一串D,就reverse一段A。 37 | 38 | ## java代码 39 | 40 | ```java 41 | class Solution { 42 | public int[] diStringMatch(String S) { 43 | int[] A = new int[S.length()+1]; 44 | for(int i=0;i<=S.length();i++){ 45 | A[i] = i; 46 | } 47 | char[] c = S.toCharArray(); 48 | int count=0; 49 | for(int i=0;ic[i][ColumnNums]){ 70 | return false; 71 | } 72 | } 73 | return true; 74 | } 75 | } 76 | ``` -------------------------------------------------------------------------------- /第一遍/946. Validate Stack Sequences.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given two sequences `pushed` and `popped` **with distinct values**, return `true` if and only if this could have been the result of a sequence of push and pop operations on an initially empty stack. 4 | 5 | **Example 1:** 6 | ``` 7 | Input: pushed = [1,2,3,4,5], popped = [4,5,3,2,1] 8 | Output: true 9 | Explanation: We might do the following sequence: 10 | push(1), push(2), push(3), push(4), pop() -> 4, 11 | push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1 12 | ``` 13 | 14 | **Example 2:** 15 | ``` 16 | Input: pushed = [1,2,3,4,5], popped = [4,3,5,1,2] 17 | Output: false 18 | Explanation: 1 cannot be popped before 2. 19 | ``` 20 | 21 | **Note:** 22 | 23 | 1. `0 <= pushed.length == popped.length <= 1000` 24 | 2. `0 <= pushed[i], popped[i] < 1000` 25 | 3. `pushed` is a permutation of `popped`. 26 | 4. `pushed` and `popped` have distinct values. 27 | 28 | [题目地址](https://leetcode.com/problems/validate-stack-sequences/) 29 | 30 | ## 讲解 31 | 32 | 典型的栈的题目,练习此题,有助于加深对栈的理解和运用。 33 | 34 | ## java代码 35 | 36 | ```java 37 | class Solution { 38 | public boolean validateStackSequences(int[] pushed, int[] popped) { 39 | Stack stack = new Stack<>(); 40 | int index=0; 41 | for(int i=0;i queue = new LinkedList<>(); 56 | for(int i=0;i0;i++){ 61 | if(i%2==0){ 62 | map[count++]=queue.poll(); 63 | }else{ 64 | queue.offer(queue.poll()); 65 | } 66 | } 67 | Arrays.sort(deck); 68 | int[] result = new int[deck.length]; 69 | for(int i=0;i words[1], hence the sequence is unsorted. 19 | ``` 20 | 21 | **Example 3:** 22 | ``` 23 | Input: words = ["apple","app"], order = "abcdefghijklmnopqrstuvwxyz" 24 | Output: false 25 | Explanation: The first three characters "app" match, and the second string is shorter (in size.) According to lexicographical rules "apple" > "app", because 'l' > '∅', where '∅' is defined as the blank character which is less than any other character (More info). 26 | ``` 27 | 28 | **Note:** 29 | 30 | 1. `1 <= words.length <= 100` 31 | 2. `1 <= words[i].length <= 20` 32 | 3. `order.length == 26` 33 | 4. All characters in `words[i]` and `order` are english lowercase letters. 34 | 35 | [题目地址](https://leetcode.com/problems/verifying-an-alien-dictionary/) 36 | 37 | ## 讲解 38 | 39 | 这道题讲道理,我觉得有点难。可能递归的解法比较简单吧。刚开始我思路一直是错的,正确的思路应该是先深入比较两个字符串,没有问题再比较下一对字符串(这是一种深度优先,我刚开始一直是广度优先的思路)。主要的麻烦来自于对数组越界的判断。 40 | 41 | ## java代码 42 | 43 | ```java 44 | class Solution { 45 | public boolean isAlienSorted(String[] words, String order) { 46 | if(words.length==1){ 47 | return true; 48 | } 49 | Map map = new HashMap<>(); 50 | for(int i=0;iwords[i-1].length()-1){ 57 | continue; 58 | } 59 | if(index>words[i].length()-1){ 60 | return false; 61 | } 62 | while(map.get(words[i].charAt(index))==map.get(words[i-1].charAt(index))){ 63 | index++; 64 | System.out.println(index); 65 | if(index>words[i-1].length()-1){ 66 | indexOut=true; 67 | break; 68 | } 69 | if(index>words[i].length()-1){ 70 | return false; 71 | } 72 | } 73 | if(indexOut){ 74 | continue; 75 | } 76 | if(map.get(words[i].charAt(index)) map = new HashMap<>(); 45 | for(int x:A){ 46 | Integer count = map.get(x); 47 | if(count==null){ 48 | map.put(x, 1); 49 | }else{ 50 | return x; 51 | } 52 | } 53 | return 0; 54 | } 55 | } 56 | ``` 57 | -------------------------------------------------------------------------------- /第一遍/965. Univalued Binary Tree.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | A binary tree is univalued if every node in the tree has the same value. 4 | 5 | Return `true` if and only if the given tree is univalued. 6 | 7 | **Example 1:** 8 | 9 | ![](https://assets.leetcode.com/uploads/2018/12/28/unival_bst_1.png) 10 | 11 | ``` 12 | Input: [1,1,1,1,1,null,1] 13 | Output: true 14 | ``` 15 | 16 | **Example 2:** 17 | 18 | ![](https://assets.leetcode.com/uploads/2018/12/28/unival_bst_2.png) 19 | ``` 20 | Input: [2,2,2,5,2] 21 | Output: false 22 | ``` 23 | 24 | **Note:** 25 | 26 | 1. The number of nodes in the given tree will be in the range `[1, 100]`. 27 | 2. Each node's value will be an integer in the range `[0, 99]`. 28 | 29 | [题目地址](https://leetcode.com/problems/univalued-binary-tree/) 30 | 31 | ## 讲解 32 | 33 | 这题很简单,需要注意的一点是,碰到不相等就返回,而不是遍历整个树之后才返回,这样可以优化速度。 34 | 35 | ## java代码 36 | 37 | ```java 38 | /** 39 | * Definition for a binary tree node. 40 | * public class TreeNode { 41 | * int val; 42 | * TreeNode left; 43 | * TreeNode right; 44 | * TreeNode(int x) { val = x; } 45 | * } 46 | */ 47 | class Solution { 48 | private boolean flag=true; 49 | private int val = 0; 50 | public boolean isUnivalTree(TreeNode root) { 51 | if(root==null){ 52 | return true; 53 | } 54 | if(flag){ 55 | val = root.val; 56 | flag = false; 57 | }else if(val!=root.val){ 58 | return false; 59 | } 60 | if(!isUnivalTree(root.left)){ 61 | return false; 62 | }else{ 63 | return isUnivalTree(root.right); 64 | } 65 | } 66 | } 67 | ``` -------------------------------------------------------------------------------- /第一遍/969. Pancake Sorting.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given an array `A`, we can perform a pancake flip: We choose some positive integer `k <= A.length`, then reverse the order of the first **k** elements of `A`. We want to perform zero or more pancake flips (doing them one after another in succession) to sort the array `A`. 4 | 5 | Return the k-values corresponding to a sequence of pancake flips that sort `A`. Any valid answer that sorts the array within `10 * A.length` flips will be judged as correct. 6 | 7 | **Example 1:** 8 | ``` 9 | Input: [3,2,4,1] 10 | Output: [4,2,4,3] 11 | Explanation: 12 | We perform 4 pancake flips, with k values 4, 2, 4, and 3. 13 | Starting state: A = [3, 2, 4, 1] 14 | After 1st flip (k=4): A = [1, 4, 2, 3] 15 | After 2nd flip (k=2): A = [4, 1, 2, 3] 16 | After 3rd flip (k=4): A = [3, 2, 1, 4] 17 | After 4th flip (k=3): A = [1, 2, 3, 4], which is sorted. 18 | ``` 19 | 20 | **Example 2:** 21 | ``` 22 | Input: [1,2,3] 23 | Output: [] 24 | Explanation: The input is already sorted, so there is no need to flip anything. 25 | Note that other answers, such as [3, 3], would also be accepted. 26 | ``` 27 | 28 | **Note:** 29 | 30 | 1. `1 <= A.length <= 100` 31 | 2. `A[i]` is a permutation of `[1, 2, ..., A.length]` 32 | 33 | [题目地址](https://leetcode.com/problems/pancake-sorting/) 34 | 35 | ## 讲解 36 | 37 | 这题我首先想到的就是选择排序,选择排序需要的pancakesort最多是2倍`A.length`。先选出最大的数,然后进行两次pancakesort将其沉入最后。 38 | 39 | ## java代码 40 | 41 | ```java 42 | class Solution { 43 | private List result = new ArrayList<>(); 44 | public List pancakeSort(int[] A) { 45 | if(A.length<=1){ 46 | return result; 47 | } 48 | int index = A.length-1; 49 | int max = A[index]; 50 | for(int i=A.length-1;i>=0;i--){ 51 | if(max0){ 59 | result.add(index+1); 60 | } 61 | result.add(A.length); 62 | pancakeSort(A, A.length-2); 63 | return result; 64 | } 65 | 66 | private void pancakeSort(int[] A, int endIndex) { 67 | if(endIndex<0){ 68 | return ; 69 | } 70 | int index = endIndex; 71 | int max = A[index]; 72 | for(int i=endIndex;i>=0;i--){ 73 | if(max0){ 81 | result.add(index+1); 82 | } 83 | if(endIndex>0){ 84 | result.add(endIndex+1); 85 | } 86 | pancakeSort(A, endIndex-1); 87 | } 88 | 89 | private void reverse(int[] A, int left, int right){ 90 | if(left==right){ 91 | return; 92 | } 93 | for(int i=0;i<(right-left+1)/2;i++){ 94 | int temp = A[left+i]; 95 | A[left+i] = A[right-i]; 96 | A[right-i] = temp; 97 | } 98 | } 99 | } 100 | ``` -------------------------------------------------------------------------------- /第一遍/973. K Closest Points to Origin.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | We have a list of `points` on the plane. Find the `K` closest points to the origin `(0, 0)`. 4 | 5 | (Here, the distance between two points on a plane is the Euclidean distance.) 6 | 7 | You may return the answer in any order. The answer is guaranteed to be unique (except for the order that it is in.) 8 | 9 | **Example 1:** 10 | ``` 11 | Input: points = [[1,3],[-2,2]], K = 1 12 | Output: [[-2,2]] 13 | Explanation: 14 | The distance between (1, 3) and the origin is sqrt(10). 15 | The distance between (-2, 2) and the origin is sqrt(8). 16 | Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin. 17 | We only want the closest K = 1 points from the origin, so the answer is just [[-2,2]]. 18 | ``` 19 | 20 | **Example 2:** 21 | ``` 22 | Input: points = [[3,3],[5,-1],[-2,4]], K = 2 23 | Output: [[3,3],[-2,4]] 24 | (The answer [[-2,4],[3,3]] would also be accepted.) 25 | ``` 26 | 27 | **Note:** 28 | 29 | 1. `1 <= K <= points.length <= 10000` 30 | 2. `-10000 < points[i][0] < 10000` 31 | 3. `-10000 < points[i][1] < 10000` 32 | 33 | [题目地址](https://leetcode.com/problems/k-closest-points-to-origin/) 34 | 35 | ## 讲解 36 | 37 | 刚开始没仔细看题,还以为是求第K个距离最近的,结果是求第K个以及第K个以前的所有点。看Exmaple 2就知道了。 38 | 39 | 这个题目的本质是定义了一种比较规则,所以实际上我们只需要写一个compare函数让sort库函数调用即可。 40 | 41 | ## python代码 42 | 43 | ```python 44 | class Solution: 45 | def kClosest(self, points, K): 46 | """ 47 | :type points: List[List[int]] 48 | :type K: int 49 | :rtype: List[List[int]] 50 | """ 51 | points.sort(key=lambda x:x[0]**2+x[1]**2) 52 | return points[:K] 53 | ``` 54 | 55 | ## C++代码 56 | 57 | ```C++ 58 | class Solution { 59 | public: 60 | vector> kClosest(vector>& points, int K) { 61 | sort(points.begin(), points.end(), less); 62 | return vector>(points.begin(), points.begin()+K); 63 | } 64 | 65 | private: 66 | static bool less(vector a, vector b){ 67 | return a[0]*a[0]+a[1]*a[1]() { 96 | @Override 97 | public int compare(int[] o1, int[] o2) { 98 | return o1[0]*o1[0]+o1[1]*o1[1]-o2[0]*o2[0]-o2[1]*o2[1]; 99 | } 100 | }); 101 | return Arrays.copyOfRange(points, 0, K); 102 | } 103 | } 104 | ``` -------------------------------------------------------------------------------- /第一遍/976. Largest Perimeter Triangle.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | Given an array `A` of positive lengths, return the largest perimeter of a triangle with **non-zero area**, formed from 3 of these lengths. 4 | 5 | If it is impossible to form any triangle of non-zero area, return `0`. 6 | 7 | **Example 1:** 8 | ``` 9 | Input: [2,1,2] 10 | Output: 5 11 | ``` 12 | 13 | **Example 2:** 14 | ``` 15 | Input: [1,2,1] 16 | Output: 0 17 | ``` 18 | 19 | **Example 3:** 20 | ``` 21 | Input: [3,2,3,4] 22 | Output: 10 23 | ``` 24 | 25 | **Example 4:** 26 | ``` 27 | Input: [3,6,2,3] 28 | Output: 8 29 | ``` 30 | 31 | **Note:** 32 | 33 | 1. `3 <= A.length <= 10000` 34 | 2. `1 <= A[i] <= 10^6` 35 | 36 | [题目地址](https://leetcode.com/problems/largest-perimeter-triangle/) 37 | 38 | ## 讲解 39 | 40 | 求数组中能组成最大周长的三角形的周长。方法很简单,先对数组进行一个排序,然后遍历数组,如果三个数的最大数比另外两个数都大,那就不能构成三角形,就要放弃这个最大数,接着找。 41 | 42 | ## python代码 43 | 44 | ```python 45 | class Solution: 46 | def largestPerimeter(self, A): 47 | """ 48 | :type A: List[int] 49 | :rtype: int 50 | """ 51 | if len(A)<3: 52 | return 0 53 | A.sort() 54 | i = len(A)-1 55 | while i>1: 56 | if A[i]& A) { 69 | if(A.size()<3){ 70 | return 0; 71 | } 72 | sort(A.begin(), A.end()); 73 | for(int i=A.size()-1;i>1;i--){ 74 | if(A[i]1;i--){ 95 | if(A[i]1;i--){ 113 | if(A[i] map = new HashMap<>(); 68 | public int distributeCoins(TreeNode root) { 69 | if(root==null){ 70 | return result; 71 | } 72 | result += Math.abs(need(root.left))+Math.abs(need(root.right)); 73 | distributeCoins(root.left); 74 | distributeCoins(root.right); 75 | return result; 76 | } 77 | 78 | private int need(TreeNode node){ 79 | if(node==null){ 80 | return 0; 81 | } 82 | if(map.get(node)!=null){ 83 | return map.get(node); 84 | } 85 | int needs = 1-node.val+need(node.left)+need(node.right); 86 | map.put(node, needs); 87 | return needs; 88 | } 89 | } 90 | ``` -------------------------------------------------------------------------------- /第一遍/993. Cousins in Binary Tree.md: -------------------------------------------------------------------------------- 1 | ## 题目 2 | 3 | In a binary tree, the root node is at depth `0`, and children of each depth `k` node are at depth `k+1`. 4 | 5 | Two nodes of a binary tree are cousins if they have the same depth, but have **different parents**. 6 | 7 | We are given the `root` of a binary tree with unique values, and the values `x` and `y` of two different nodes in the tree. 8 | 9 | Return true if and only if the nodes corresponding to the values x and y are cousins. 10 | 11 | **Example 1:** 12 | 13 | ![](https://assets.leetcode.com/uploads/2019/02/12/q1248-01.png) 14 | ``` 15 | Input: root = [1,2,3,4], x = 4, y = 3 16 | Output: false 17 | ``` 18 | 19 | **Example 2:** 20 | ![](https://assets.leetcode.com/uploads/2019/02/12/q1248-02.png) 21 | ``` 22 | Input: root = [1,2,3,null,4,null,5], x = 5, y = 4 23 | Output: true 24 | ``` 25 | 26 | **Example 3:** 27 | ![](https://assets.leetcode.com/uploads/2019/02/13/q1248-03.png) 28 | ``` 29 | Input: root = [1,2,3,null,4], x = 2, y = 3 30 | Output: false 31 | ``` 32 | 33 | **Note:** 34 | 35 | 1. The number of nodes in the tree will be between `2` and `100`. 36 | 2. Each node has a unique integer value from `1` to `100`. 37 | 38 | [题目地址](https://leetcode.com/problems/cousins-in-binary-tree/) 39 | 40 | ## 讲解 41 | 42 | 这道题刚开始我觉得还挺难的,我觉得我需要构造两个函数,一个`getDepth`,一个`getParent`。这样就需要遍历四遍树。实际上只需要遍历两遍,因为`depth`和`parent`可以同时取出来。如果借助存储的话,实际只需要遍历一遍。 43 | 44 | ## java代码 45 | 46 | ```java 47 | /** 48 | * Definition for a binary tree node. 49 | * public class TreeNode { 50 | * int val; 51 | * TreeNode left; 52 | * TreeNode right; 53 | * TreeNode(int x) { val = x; } 54 | * } 55 | */ 56 | class Solution { 57 | List list = new ArrayList<>(); 58 | public boolean isCousins(TreeNode root, int x, int y) { 59 | dfs(root, root, 0, x, y); 60 | if(list.size()==2 && list.get(0).depth==list.get(1).depth && list.get(0).parent!=list.get(1).parent){ 61 | return true; 62 | } 63 | return false; 64 | } 65 | 66 | private void dfs(TreeNode node, TreeNode par, int d, int x, int y){ 67 | if(node==null){ 68 | return; 69 | } 70 | if(node.val==x || node.val==y){ 71 | list.add(new Pair(par.val, d)); 72 | } 73 | dfs(node.left, node, d+1, x, y); 74 | if(list.size()==2){ 75 | return; 76 | } 77 | dfs(node.right, node, d+1, x, y); 78 | } 79 | 80 | class Pair{ 81 | int parent; 82 | int depth; 83 | public Pair(int parent, int depth){ 84 | this.parent = parent; 85 | this.depth = depth; 86 | } 87 | } 88 | } 89 | ``` 90 | -------------------------------------------------------------------------------- /第一遍/README.md: -------------------------------------------------------------------------------- 1 | # 第一遍,按AC率刷题 2 | -------------------------------------------------------------------------------- /第二遍/801. Minimum Swaps To Make Sequences Increasing.md: -------------------------------------------------------------------------------- 1 | ## 801. Minimum Swaps To Make Sequences Increasing 2 | 3 | [题目地址](https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing/) 4 | 5 | ### 代码 6 | 7 | ```typescript 8 | function minSwap(nums1: number[], nums2: number[]): number { 9 | if(nums1.length<=1){ 10 | return 0; 11 | } 12 | let dp = [[0,1]]; 13 | for(let i=1;inums1[i-1] && nums2[i]>nums2[i-1] && nums1[i]>nums2[i-1] && nums2[i]>nums1[i-1]){ 17 | // 情况1:原本是有序的,互换后有序 18 | // 如果i不互换,则i-1可以互换也可以不互换 19 | dp[i][0] = Math.min(dp[i-1][0], dp[i-1][1]); 20 | // 如果i互换,则i-1可以互换也可以不互换 21 | dp[i][1] = dp[i][0]+1; 22 | }else if(nums1[i]>nums1[i-1] && nums2[i]>nums2[i-1] && (nums1[i]<=nums2[i-1] || nums2[i]<=nums1[i-1])){ 23 | // 情况2:原本是有序的,互换后无序 24 | // 如果i不互换,则i-1必定没互换 25 | dp[i][0] = dp[i-1][0]; 26 | // 如果i互换,则i-1必定互换了 27 | dp[i][1] = dp[i-1][1]+1; 28 | }else{ 29 | // 情况3:原本是无序的,互换后有序(情况4:原本无序,互换后还无序,不存在) 30 | // 如果i不互换,则i-1必定互换了 31 | dp[i][0] = dp[i-1][1]; 32 | // 如果i互换,则i-1必定没互换 33 | dp[i][1] = dp[i-1][0]+1; 34 | } 35 | } 36 | return Math.min(dp[nums1.length-1][0], dp[nums1.length-1][1]); 37 | }; 38 | ``` 39 | -------------------------------------------------------------------------------- /第二遍/README.md: -------------------------------------------------------------------------------- 1 | # 第二遍,按算法体系总结 2 | 3 | ## 动态规划 4 | 5 | - [801. 使序列递增的最小交换次数](https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing/) 6 | --------------------------------------------------------------------------------