├── 001.two-sum ├── question&solution.txt ├── two_sum.cpp ├── two_sum.java └── two_sum.py ├── 002.add-two-numbers ├── add_two_numbers.cpp ├── add_two_numbers.py └── question&solution.md ├── 003.longest substring without repeating ├── longest_substring_without_repeating.py └── question&solution ├── 004.median-of-two-sorted-arrays ├── 004.median-of-two-sorted-arrays.cpp ├── 004.median-of-two-sorted-arrays.java ├── 004.median-of-two-sorted-arrays.py └── question&solution ├── 005.longest-palindromic-substring ├── 005.longest-palindromic-substring.py └── question.txt ├── 006.zigzag-conversion ├── 006.zigzag-conversion.cpp ├── 006.zigzag-conversion.java ├── 006.zigzag-conversion.py └── question.txt ├── 007.reverse-integer ├── 007.reverse-integer.cpp ├── 007.reverse-integer.java ├── 007.reverse-integer.py └── question.txt ├── 008.string-to-integer-atoi ├── 008.string-to-integer-atoi.cpp ├── 008.string-to-integer-atoi.java ├── 008.string-to-integer-atoi.py └── question&solution.txt ├── 009.palindrome-number ├── 009.palindrome-number.cs ├── 009.palindrome-number.java ├── 009.palindrome-number.py └── question&solution.md ├── 010.regular-expression-matching ├── 010.regular-expression-matching.cpp ├── 010.regular-expression-matching.java ├── 010.regular-expression-matching.py └── question&solution.md ├── 011.container-with-most-water ├── 011.container-with-most-water.cpp ├── 011.container-with-most-water.java ├── 011.container-with-most-water.py ├── 011.container-with-most-water_2.java └── question&solution.md ├── 012.integer-to-roman ├── 012.integer-to-roman.py ├── 012.integer-to-roman_2.py ├── 012.integer-to-roman_by辰星.py ├── integer-to-roman_by李振兴.py └── question&solution.md ├── 013.Roman_to_int ├── 013.Roman_to_int.py └── question&solution.md ├── 014.Longest Common Prefix ├── 014.Longest Common Prefix.cpp ├── 014.Longest Common Prefix.java ├── 014.Longest Common Prefix.py └── README.md ├── 020.valid-parentheses ├── 020.valid-parentheses.py ├── 020.valid-parentheses_2.py └── question&solution.md ├── 021.merge-two-sorted-lists ├── 012.merge-two-sorted-lists.java ├── 012.merge-two-sorted-lists.py └── question&solution.md ├── 026.RemoveDuplicates fromSorted Array ├── 026.RemoveDuplicates fromSorted Array.cpp ├── 026.RemoveDuplicates fromSorted Array.java ├── 026.RemoveDuplicates fromSorted Array.py └── README.md ├── 027.Remove Element ├── 027.Remove Element.cpp ├── 027.Remove Element.java ├── 027.Remove Element.py └── README.md ├── 028.Implement strStr() ├── 028.Implement strStr().cpp ├── 028.Implement strStr().java ├── 028.Implement strStr().py └── README.md ├── 032. Longest Valid Parentheses—Dynamic Programming ├── Longest Valid Parentheses.cpp ├── Longest Valid Parentheses.java ├── Longest Valid Parentheses.py └── Readme.md ├── 033. Search in Rotated Sorted Array ├── 033. Search in Rotated Sorted Array.cpp ├── 033. Search in Rotated Sorted Array.java ├── 033. Search in Rotated Sorted Array.py └── Readme.txt ├── 035.Search Insert Position ├── 035.Search Insert Position.cpp ├── 035.Search Insert Position.java ├── 035.Search Insert Position.py └── README.md ├── 038. Count and Say ├── Count and Say.cpp ├── Count and Say.java ├── Count and Say_2.py ├── Readme.md └── count and say.py ├── 039. Combination Sum ├── Combination Sum.cpp ├── Combination Sum.java ├── Combination Sum.py └── Readme.md ├── 040. Combination Sum II ├── Combination Sum II.cpp ├── Combination Sum II.java ├── Combination Sum II.py └── Readme.md ├── 042.Trapping Rain Water ├── Trapping Rain Water.cpp ├── Trapping Rain Water.java └── Trapping Rain Water.py ├── 045.Jump Game II ├── Jump Game II.cpp ├── Jump Game II.java ├── Jump Game II.py └── Readme.md ├── 046. Permutations ├── Permutations.cpp ├── Permutations.java ├── Permutations.py └── Readme.md ├── 058. Length of Last Word ├── 58. Length of Last Word.cpp ├── 58. Length of Last Word.java ├── 58. Length of Last Word.py └── readme.md ├── 060. Permutation Sequence ├── 60. Permutation Sequence.cpp ├── 60. Permutation Sequence.java └── 60. Permutation Sequence.py ├── 062. Unique Paths—Dynamic Programming ├── Readme.md ├── Unique Paths.cpp ├── Unique Paths.java └── Unique Paths.py ├── 063. Unique Paths II—Dynamic Programming ├── Readme.md ├── Unique Paths II.cpp ├── Unique Paths II.java └── Unique Paths II.py ├── 064. Minimum Path Sum—Dynamic Programming ├── Minimum Path Sum.cpp ├── Minimum Path Sum.java ├── Minimum Path Sum.py └── Readme.md ├── 067. Add Binary ├── 067. Add Binary.cpp ├── 067. Add Binary.java ├── 067. Add Binary.py └── readme.md ├── 067.Add Binary 二进制数相加 ├── 067.Add Binary 二进制数相加.cpp ├── 067.Add Binary 二进制数相加.java ├── 067.Add Binary 二进制数相加.py └── readme.md ├── 069. Sqrt(x) ├── 069. Sqrt(x).cpp ├── 069. Sqrt(x).java ├── 069. Sqrt(x).py └── reademe.md ├── 070. Climbing Stairs ├── 070. Climbing Stairs.cpp ├── 070. Climbing Stairs.java ├── 070. Climbing Stairs.py └── readme.md ├── 071.Simplify Path ├── Simplify Path.cpp ├── Simplify Path.java └── Simplify Path.py ├── 074. Search a 2D Matrix ├── 74. Search a 2D Matrix.cpp ├── 74. Search a 2D Matrix.java ├── 74. Search a 2D Matrix.py └── Readme.txt ├── 075.Sort Colors ├── 075.Sort Colors.cpp ├── 075.Sort Colors.java ├── 075.Sort Colors.js ├── 075.Sort Colors.py └── Readme.md ├── 083. Remove Duplicates from Sorted List ├── 083. Remove Duplicates from Sorted List.cpp ├── 083. Remove Duplicates from Sorted List.java ├── 083. Remove Duplicates from Sorted List.py └── readme.md ├── 084.Largest Rectangle in Histogram ├── Largest Rectangle in Histogram.cpp ├── Largest Rectangle in Histogram.java └── Largest Rectangle in Histogram.py ├── 085.Maximal Rectangle ├── Maximal Rectangle.cpp ├── Maximal Rectangle.java └── Maximal Rectangle.py ├── 088. Merge Sorted Array ├── 088. Merge Sorted Array.cpp ├── 088. Merge Sorted Array.java ├── 088. Merge Sorted Array.py └── readme.md ├── 089.Gray Code ├── 089.Gray Code.cpp ├── 089.Gray Code.java ├── 089.Gray Code.py └── readme.md ├── 090. Subsets II ├── 090. Subsets II.cpp ├── 090. Subsets II.java ├── 090. Subsets II.py └── readme.md ├── 092. Reverse Linked List II ├── 092. Reverse Linked List II.cpp ├── 092. Reverse Linked List II.java ├── 092. Reverse Linked List II.py └── readme.md ├── 094.Binary Tree Inorder Traversal ├── Binary Tree Inorder Traversal.cpp ├── Binary Tree Inorder Traversal.java └── Binary Tree Inorder Traversal.py ├── 095. Unique Binary Search Trees II—Dynamic Programming ├── Readme.md ├── Unique Binary Search Trees II.cpp ├── Unique Binary Search Trees II.java └── Unique Binary Search Trees II.py ├── 096. Unique Binary Search Trees—tree ├── Readme.md ├── Unique Binary Search Trees.cpp ├── Unique Binary Search Trees.java ├── Unique Binary Search Trees.js └── Unique Binary Search Trees.py ├── 100. Same Tree ├── 100. Same Tree.cpp ├── 100. Same Tree.java ├── 100. Same Tree.py └── Readme.txt ├── 101. Symmetric Tree—Breadth-first Search ├── 101. Symmetric Tree—Breadth-first Search.cpp ├── 101. Symmetric Tree—Breadth-first Search.java ├── 101. Symmetric Tree—Breadth-first Search.py └── Readme.txt ├── 102. Binary Tree Level Order Traversal—Breadth-first Search ├── 102. Binary Tree Level Order Traversal—Breadth-first Search.cpp ├── 102. Binary Tree Level Order Traversal—Breadth-first Search.java ├── 102. Binary Tree Level Order Traversal—Breadth-first Search.py └── Readme.txt ├── 103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search ├── 103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search.cpp ├── 103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search.java ├── 103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search.py └── Readme.txt ├── 104. Maximum Depth of Binary Tree ├── 104. Maximum Depth of Binary Tree.cpp ├── 104. Maximum Depth of Binary Tree.java ├── 104. Maximum Depth of Binary Tree.py └── Readme.txt ├── 105. Construct Binary Tree from Preorder and Inorder Traversal ├── 105. Construct Binary Tree from Preorder and Inorder Traversal.cpp ├── 105. Construct Binary Tree from Preorder and Inorder Traversal.java ├── 105. Construct Binary Tree from Preorder and Inorder Traversal.py └── readme.md ├── 107. Binary Tree Level Order Traversal II—Breadth-first Search ├── 107. Binary Tree Level Order Traversal II—Breadth-first Search.cpp ├── 107. Binary Tree Level Order Traversal II—Breadth-first Search.java ├── 107. Binary Tree Level Order Traversal II—Breadth-first Search.py └── Readme.txt ├── 108. Convert Sorted Array to Binary Search Tree ├── 108. Convert Sorted Array to Binary Search Tree.cpp ├── 108. Convert Sorted Array to Binary Search Tree.java ├── 108. Convert Sorted Array to Binary Search Tree.py └── Readme.txt ├── 110. Balanced Binary Tree ├── 110. Balanced Binary Tree.cpp ├── 110. Balanced Binary Tree.java ├── 110. Balanced Binary Tree.py └── Readme.txt ├── 111. Minimum Depth of Binary Tree—Breadth-first Search ├── 111. Minimum Depth of Binary Tree—Breadth-first Search.cpp ├── 111. Minimum Depth of Binary Tree—Breadth-first Search.java ├── 111. Minimum Depth of Binary Tree—Breadth-first Search.py └── Readme.txt ├── 112. Path Sum ├── 112. Path Sum.cpp ├── 112. Path Sum.java ├── 112. Path Sum.py └── Readme.txt ├── 121. Best Time to Buy and Sell Stock ├── 121. Best Time to Buy and Sell Stock.cpp ├── 121. Best Time to Buy and Sell Stock.java ├── 121. Best Time to Buy and Sell Stock.py └── question&solution.md ├── 123. Best Time to Buy and Sell Stock III ├── 123. Best Time to Buy and Sell Stock III.cpp ├── 123. Best Time to Buy and Sell Stock III.java ├── 123. Best Time to Buy and Sell Stock III.py └── question&solution.md ├── 125.Valid Palindrome ├── 125.Valid Palindrome.cpp ├── 125.Valid Palindrome.java ├── 125.Valid Palindrome.py └── readme.md ├── 139.Word Break ├── 139.Word Break.cpp ├── 139.Word Break.java └── 139.Word Break.py ├── 140. Word Break II ├── 140. Word Break II.cpp ├── 140. Word Break II.java └── 140. Word Break II.py ├── 141.Linked List Cycle ├── 141.Linked List Cycle.cpp ├── 141.Linked List Cycle.java ├── 141.Linked List Cycle_py.md └── readme.md ├── 142.Linked List Cycle II ├── 142.Linked List Cycle II.cpp ├── 142.Linked List Cycle II.java.md ├── 142.Linked List Cycle II.py.md └── readme.md ├── 202. Happy Number ├── 202. Happy Number.cpp ├── 202. Happy Number.java ├── 202. Happy Number.py └── Readme.md ├── 204. Count Primes ├── 204. Count Primes.cpp ├── 204. Count Primes.java ├── 204. Count Primes.py └── Readme.md ├── 215. Kth Largest Element in an Array ├── 215. Kth Largest Element in an Array.cpp ├── 215. Kth Largest Element in an Array.java ├── 215. Kth Largest Element in an Array.py └── readme.md ├── 217. Contains Duplicate ├── 217. Contains Duplicate.cpp ├── 217. Contains Duplicate.java ├── 217. Contains Duplicate.py └── Readme.md ├── 225. Implement Stack using Queues ├── 225. Implement Stack using Queues.cpp ├── 225. Implement Stack using Queues.java ├── 225. Implement Stack using Queues.py └── readme.md ├── 232. Implement Queue using Stacks ├── 232. Implement Queue using Stacks.cpp ├── 232. Implement Queue using Stacks.java ├── 232. Implement Queue using Stacks.py └── readme.md ├── 303.Range Sum Query - Immutable ├── 303.Range Sum Query - Immutable.cpp ├── 303.Range Sum Query - Immutable.java ├── 303.Range Sum Query - Immutable.md └── 303.Range Sum Query - Immutable.py ├── 304. Range Sum Query 2D - Immutable ├── 304. Range Sum Query 2D - Immutable.cpp ├── 304. Range Sum Query 2D - Immutable.java ├── 304. Range Sum Query 2D - Immutable.md └── 304. Range Sum Query 2D - Immutable.py ├── 344.Reverse String ├── 344.Reverse String.cpp ├── 344.Reverse String.java ├── 344.Reverse String.py └── readme.md ├── 346.Moving Average from Data Stream ├── 346.Moving Average from Data Stream.cpp ├── 346.Moving Average from Data Stream.java └── 346.Moving Average from Data Stream.py ├── 353.Design Snake Game ├── 353.Design Snake Game.cpp ├── 353.Design Snake Game.java └── readme.txt ├── 387.First Unique Character in a String ├── 387.First Unique Character in a String.cpp ├── 387.First Unique Character in a String.java ├── 387.First Unique Character in a String.py └── readme.md ├── 496. Next Greater Element I ├── 496. Next Greater Element I.cpp ├── 496. Next Greater Element I.java ├── 496. Next Greater Element I.py └── readme.md ├── 503. Next Greater Element II ├── 503. Next Greater Element II.cpp ├── 503. Next Greater Element II.java ├── 503. Next Greater Element II.py └── readme.md ├── 575. Distribute Candies ├── 575. Distribute Candies.cpp ├── 575. Distribute Candies.java ├── 575. Distribute Candies.py └── Readme.md ├── 621.Task Scheduler ├── 621.Task Scheduler.cpp ├── 621.Task Scheduler.java └── 621.Task Scheduler.py ├── 622. Design Circular Deque ├── 622. Design Circular Deque.cpp ├── 622. Design Circular Deque.java └── 622. Design Circular Deque.py ├── 641. Design Circular Deque ├── 641. Design Circular Deque.cpp ├── 641.Design Circular Deque.java └── 641.Design Circular Deque.py ├── 645. Set Mismatch ├── 645. Set Mismatch.cpp ├── 645. Set Mismatch.java ├── 645. Set Mismatch.py └── Readme.md ├── 647. Palindromic Substrings ├── 647. Palindromic Substrings.cpp ├── 647. Palindromic Substrings.java ├── 647. Palindromic Substrings.py └── readme.md ├── 682. Baseball Game ├── 682. Baseball Game.cpp ├── 682. Baseball Game.java ├── 682. Baseball Game.py ├── Baseball Game by Andy.md └── readme.md ├── 730. Count Different Palindromic Subsequences ├── 730. Count Different Palindromic Subsequences.cpp ├── 730. Count Different Palindromic Subsequences.java └── 730. Count Different Palindromic Subsequences.py ├── 933.Number of Recent Calls ├── 933.Number of Recent Calls.cpp ├── 933.Number of Recent Calls.java ├── 933.Number of Recent Calls.py └── readme.md ├── Counting sort algorithm-by 多年未见提议 ├── README.md ├── img-storage ├── 027.Remove Element.jpg ├── 028.Implement strStr().png ├── 035.Search Insert Position.jpg ├── 2018-10-31_181616.png ├── 225. Implement Stack using Queues.png ├── 26.RemoveDuplicates fromSorted Array.png ├── 682baseball_game.png ├── 75.leetcode.png ├── 94.stack.png ├── 96.tree.png ├── Container With Most Water.jpg ├── Implement Queue using Stacks.png ├── Longest Common Prefix.jpg ├── Roman_to_int - 副本.png ├── Roman_to_int.png ├── Unique_Paths.png ├── add_two_nums.png ├── gongzhonghao.jpg ├── readme.md └── 微信图片_20190115223824.jpg └── 面试题 ├── 1 └── readme.md ├── 2 └── readme.md └── 3 └── baidu.txt /001.two-sum/question&solution.txt: -------------------------------------------------------------------------------- 1 | Given an array of integers, return indices of the two numbers such that they add up to a specific target. 2 | 3 | You may assume that each input would have exactly one solution, and you may not use the same element twice. 4 | 5 | Example: 6 | 7 | Given nums = [2, 7, 11, 15], target = 9, 8 | 9 | Because nums[0] + nums[1] = 2 + 7 = 9, 10 | return [0, 1]. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 这道题给了我们一个数组,还有一个目标数target,让我们找到两个数字,使其和为target, 18 | 乍一看就感觉可以用暴力搜索,但是猜到OJ肯定不会允许用暴力搜索这么简单的方法, 19 | 于是去试了一下,果然是Time Limit Exceeded,这个算法的时间复杂度是O(n^2)。 20 | 那么只能想个O(n)的算法来实现,由于暴力搜索的方法是遍历所有的两个数字的组合, 21 | 然后算其和,这样虽然节省了空间,但是时间复杂度高。一般来说,我们为了提高时间的复杂度, 22 | 需要用空间来换,这算是一个trade off吧,我们只想用线性的时间复杂度来解决问题, 23 | 那么就是说只能遍历一个数字,那么另一个数字呢,我们可以事先将其存储起来,使用一个HashMap, 24 | 来建立数字和其坐标位置之间的映射,我们都知道HashMap是常数级的查找效率, 25 | 这样,我们在遍历数组的时候,用target减去遍历到的数字,就是另一个需要的数字了, 26 | 直接在HashMap中查找其是否存在即可,注意要判断查找到的数字不是第一个数字, 27 | 比如target是4,遍历到了一个2,那么另外一个2不能是之前那个2, 28 | 整个实现步骤为:先遍历一遍数组,建立HashMap映射,然后再遍历一遍,开始查找,找到则记录index。代码如下: 29 | -------------------------------------------------------------------------------- /001.two-sum/two_sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector twoSum(vector& nums, int target) { 4 | unordered_map m; 5 | vector res; 6 | for (int i = 0; i < nums.size(); ++i) { 7 | m[nums[i]] = i; 8 | } 9 | for (int i = 0; i < nums.size(); ++i) { 10 | int t = target - nums[i]; 11 | if (m.count(t) && m[t] != i) { 12 | res.push_back(i); 13 | res.push_back(m[t]); 14 | break; 15 | } 16 | } 17 | return res; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /001.two-sum/two_sum.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public int[] twoSum(int[] nums, int target) { 3 | HashMap m = new HashMap(); 4 | int[] res = new int[2]; 5 | for (int i = 0; i < nums.length; ++i) { 6 | m.put(nums[i], i); 7 | } 8 | for (int i = 0; i < nums.length; ++i) { 9 | int t = target - nums[i]; 10 | if (m.containsKey(t) && m.get(t) != i) { 11 | res[0] = i; 12 | res[1] = m.get(t); 13 | break; 14 | } 15 | } 16 | return res; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /001.two-sum/two_sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a tuple, (index1, index2) 3 | def twoSum(self, num, target): 4 | dict = {} 5 | for i in range(len(num)): 6 | x = num[i] 7 | if target-x in dict: 8 | return (dict[target-x]+1, i+1) 9 | dict[x] = i 10 | -------------------------------------------------------------------------------- /002.add-two-numbers/add_two_numbers.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { 4 | int n1 = getLength(l1), n2 = getLength(l2), diff = abs(n1 - n2); 5 | if (n1 < n2) swap(l1, l2); 6 | ListNode *dummy = new ListNode(0), *cur = dummy, *right = cur; 7 | while (diff > 0) { 8 | cur->next = new ListNode(l1->val); 9 | if (l1->val != 9) right = cur->next; 10 | cur = cur->next; 11 | l1 = l1->next; 12 | --diff; 13 | } 14 | while (l1) { 15 | int val = l1->val + l2->val; 16 | if (val > 9) { 17 | val %= 10; 18 | ++right->val; 19 | while (right->next) { 20 | right->next->val = 0; 21 | right = right->next; 22 | } 23 | right = cur; 24 | } 25 | cur->next = new ListNode(val); 26 | if (val != 9) right = cur->next; 27 | cur = cur->next; 28 | l1 = l1->next; 29 | l2 = l2->next; 30 | } 31 | return (dummy->val == 1) ? dummy : dummy->next; 32 | } 33 | int getLength(ListNode* head) { 34 | int cnt = 0; 35 | while (head) { 36 | ++cnt; 37 | head = head->next; 38 | } 39 | return cnt; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /002.add-two-numbers/question&solution.md: -------------------------------------------------------------------------------- 1 | You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. 2 | 3 | You may assume the two numbers do not contain any leading zero, except the number 0 itself. 4 | 5 | Example: 6 | 7 | Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) 8 | Output: 7 -> 0 -> 8 9 | Explanation: 342 + 465 = 807. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | `思路` 19 | 20 | 本题主要是类似数据在机器中存储的方式,我们平常所见的数据比如342, 21 | 在链表中是逆向存储的所以就成了2->4->3这样了,同样5 -> 6 -> 4就是465, 22 | 如果这样转换后,我们就会发现342+465=807,在十位上相加是超过10向前进一, 23 | 但是链表是逆向的,所以就是向后进一。  24 | 因此,本题可以把链表中的元素转换为相应的数据后进行相加,得到的结果在按照相应的格式放入链表中。 25 | 也可以直接按照链表的方式进行相加,在相加的过程中判断其是否要进位,如果需要进位是向后进位的。 26 | 27 | 28 | `官方解法` 29 | 30 | 根据官方solution的方法,可以采用一个进位carry方便的完成一次遍历得出结果,不过过程稍微麻烦。 31 | 32 | ![add_two_nums](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/add_two_nums.png?raw=true) 33 | 34 | 两个要注意的地方:如果列表长度不相等;如果列表相加完成最后仍有进位位。 35 | -------------------------------------------------------------------------------- /003.longest substring without repeating/question&solution: -------------------------------------------------------------------------------- 1 | Given a string, find the length of the longest substring without repeating characters. 2 | 3 | Example 1: 4 | 5 | Input: "abcabcbb" 6 | Output: 3 7 | Explanation: The answer is "abc", with the length of 3. 8 | Example 2: 9 | 10 | Input: "bbbbb" 11 | Output: 1 12 | Explanation: The answer is "b", with the length of 1. 13 | Example 3: 14 | 15 | Input: "pwwkew" 16 | Output: 3 17 | Explanation: The answer is "wke", with the length of 3. 18 | Note that the answer must be a substring, "pwke" is a subsequence and not a substring. 19 | 20 | 21 | 22 | 23 | 24 | 分析 25 | 思路:用2个变量(start, end)分别保存子串的起点和终点。end自增,直到遇到重复字符为止;从重复字符出现的位置之后1位重新开始扫描。 26 | -------------------------------------------------------------------------------- /004.median-of-two-sorted-arrays/004.median-of-two-sorted-arrays.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | 3 | public: 4 | 5 | double findMedianSortedArrays(vector& nums1, vector& nums2) { 6 | 7 | int m = nums1.size(), n = nums2.size(), left = (m + n + 1) / 2, right = (m + n + 2) / 2; 8 | 9 | return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0; 10 | 11 | } 12 | 13 | int findKth(vector& nums1, int i, vector& nums2, int j, int k) { 14 | 15 | if (i >= nums1.size()) return nums2[j + k - 1]; 16 | 17 | if (j >= nums2.size()) return nums1[i + k - 1]; 18 | 19 | if (k == 1) return min(nums1[i], nums2[j]); 20 | 21 | int midVal1 = (i + k / 2 - 1 < nums1.size()) ? nums1[i + k / 2 - 1] : INT_MAX; 22 | 23 | int midVal2 = (j + k / 2 - 1 < nums2.size()) ? nums2[j + k / 2 - 1] : INT_MAX; 24 | 25 | if (midVal1 < midVal2) { 26 | 27 | return findKth(nums1, i + k / 2, nums2, j, k - k / 2); 28 | 29 | } else { 30 | 31 | return findKth(nums1, i, nums2, j + k / 2, k - k / 2); 32 | 33 | } 34 | 35 | } 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /004.median-of-two-sorted-arrays/004.median-of-two-sorted-arrays.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public double findMedianSortedArrays(int[] nums1, int[] nums2) { 3 | int m = nums1.length, n = nums2.length, left = (m + n + 1) / 2, right = (m + n + 2) / 2; 4 | return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0; 5 | } 6 | int findKth(int[] nums1, int i, int[] nums2, int j, int k) { 7 | if (i >= nums1.length) return nums2[j + k - 1]; 8 | if (j >= nums2.length) return nums1[i + k - 1]; 9 | if (k == 1) return Math.min(nums1[i], nums2[j]); 10 | int midVal1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE; 11 | int midVal2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE; 12 | if (midVal1 < midVal2) { 13 | return findKth(nums1, i + k / 2, nums2, j, k - k / 2); 14 | } else { 15 | return findKth(nums1, i, nums2, j + k / 2, k - k / 2); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /005.longest-palindromic-substring/question.txt: -------------------------------------------------------------------------------- 1 | Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. 2 | 3 | Example 1: 4 | 5 | Input: "babad" 6 | Output: "bab" 7 | Note: "aba" is also a valid answer. 8 | Example 2: 9 | 10 | Input: "cbbd" 11 | Output: "bb" 12 | 13 | 找到一个字符串的最长回文子字符串,该字符串长度不超过1000,且只有唯一一个最长回文子串。 14 | 注意点: 15 | ·返回结果是整个子字符串,不是它的长度 16 | ·回文字符串要考虑奇偶的情况例子: 17 | 输入:s="abae" 18 | 输出:aba输入:s="abbae" 19 | 输出:abba 20 | -------------------------------------------------------------------------------- /006.zigzag-conversion/006.zigzag-conversion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string convert(string s, int numRows) { 4 | 5 | if (numRows == 1) return s; 6 | 7 | vector rows(min(numRows, int(s.size()))); 8 | int curRow = 0; 9 | bool goingDown = false; 10 | 11 | for (char c : s) { 12 | rows[curRow] += c; 13 | if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown; 14 | curRow += goingDown ? 1 : -1; 15 | } 16 | 17 | string ret; 18 | for (string row : rows) ret += row; 19 | return ret; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /006.zigzag-conversion/006.zigzag-conversion.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def convert(self, s, numRows): 3 | """ 4 | :type s: str 5 | :type numRows: int 6 | :rtype: str 7 | """ 8 | str_length = len(s) 9 | ans = "" 10 | if numRows <= 1: 11 | return s 12 | for i in range(numRows): 13 | c1 = 2*numRows - 2*(i+1) 14 | c2 = 2 * i 15 | cnt = i 16 | 17 | ans += s[cnt] 18 | while cnt < str_length: 19 | if c1 != 0: 20 | cnt += c1 21 | if cnt < str_length: 22 | ans += s[cnt] 23 | if c2 != 0: 24 | cnt += c2 25 | if cnt < str_length: 26 | ans += s[cnt] 27 | 28 | return ans 29 | -------------------------------------------------------------------------------- /006.zigzag-conversion/question.txt: -------------------------------------------------------------------------------- 1 | The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) 2 | 3 | P A H N 4 | A P L S I I G 5 | Y I R 6 | And then read line by line: "PAHNAPLSIIGYIR" 7 | 8 | Write the code that will take a string and make this conversion given a number of rows: 9 | 10 | string convert(string s, int numRows); 11 | Example 1: 12 | 13 | Input: s = "PAYPALISHIRING", numRows = 3 14 | Output: "PAHNAPLSIIGYIR" 15 | Example 2: 16 | 17 | Input: s = "PAYPALISHIRING", numRows = 4 18 | Output: "PINALSIGYAHRPI" 19 | Explanation: 20 | 21 | P I N 22 | A L S I G 23 | Y A H R 24 | P I 25 | 26 | 将字符串“PAYPALISHIRING”以Z字形排列成给定的行数: 27 | PA H N APLSIIG YI R之后从左往右,逐行读取字符:"PAHNAPLSIIGYIR" 28 | 实现一个将字符串进行指定行数变换的函数: 29 | string convert(strings,int numRows);示例1: 30 | 输入:s="PAYPALISHIRING",numRows=3输出:“PAHNAPLSIIGYIR" 31 | 32 | 33 | 34 | 35 | 36 | 思路 37 | 通过从左向右迭代字符串,我们可以轻松地确定字符位于 Z 字形图案中的哪一行。 38 | 39 | 算法 40 | 我们可以使用 min(numRows,len(s))个列表来表示 Z 字形图案中的非空行。 41 | 从左到右迭代 s,将每个字符添加到合适的行。可以使用当前行和当前方向这两个变量对合适的行进行跟踪。只有当我们向上移动到最上面的行或向下移动到最下面的行时,当前方向才会发生改变。 42 | -------------------------------------------------------------------------------- /007.reverse-integer/007.reverse-integer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int reverse(int x) { 4 | int rev = 0; 5 | while (x != 0) { 6 | int pop = x % 10; 7 | x /= 10; 8 | if (rev > INT_MAX/10 || (rev == INT_MAX / 10 && pop > 7)) return 0; 9 | if (rev < INT_MIN/10 || (rev == INT_MIN / 10 && pop < -8)) return 0; 10 | rev = rev * 10 + pop; 11 | } 12 | return rev; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /007.reverse-integer/007.reverse-integer.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int reverse(int c) { 3 | 4 | int temp = 0; 5 | int rev=0; 6 | while (c != 0) { 7 | rev = rev * 10 + c%10; 8 | if(temp!=rev/10){ 9 | return 0; 10 | } 11 | temp =rev; 12 | c = c/10; 13 | } 14 | return rev; 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /007.reverse-integer/007.reverse-integer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverse(self, x): 3 | """ 4 | :type x: int 5 | :rtype: int 6 | """ 7 | if x == -2 ** 31: 8 | return 0 9 | reversestr = '' 10 | if x < 0: 11 | reversestr = '-' 12 | x = abs(x) 13 | string = str(x) 14 | for i in range(len(string) - 1, -1, -1): 15 | if i == len(string) - 1 and string[i] == 0: 16 | continue 17 | reversestr += string[i] 18 | x = int(reversestr) 19 | if x < -2 ** 31 or x > 2 ** 31 - 1: 20 | return 0 21 | else: 22 | return x 23 | x = 1534236469 24 | sol = Solution() 25 | print(sol.reverse(x)) 26 | -------------------------------------------------------------------------------- /007.reverse-integer/question.txt: -------------------------------------------------------------------------------- 1 | Given a 32-bit signed integer, reverse digits of an integer. 2 | 3 | Example 1: 4 | 5 | Input: 123 6 | Output: 321 7 | Example 2: 8 | 9 | Input: -123 10 | Output: -321 11 | Example 3: 12 | 13 | Input: 120 14 | Output: 21 15 | Note: 16 | Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. 17 | For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. 18 | 19 | 给定一个32位有符号整数,将整数中的数字进行反转。 20 | 示例1:输入:123输出:321示例2: 21 | 输入:-123输出:-321示例3:输入:120输出:21注意: 22 | 假设我们的环境只能存倩32.位有符号整数,其数值范围是[-2^31,2^31-1.根据这个假设,如果反转后的整数产出,则返回0。 23 | 24 | 25 | 方法:弹出和推入数字 & 溢出前进行检查 26 | 思路 27 | 我们可以一次构建反转整数的一位数字。在这样做的时候,我们可以预先检查向原整数附加另一位数字是否会导致溢出。 28 | 算法 29 | 反转整数的方法可以与反转字符串进行类比。 30 | 我们想重复“弹出” x的最后一位数字,并将它“推入”到 \text{rev} 31 | rev 的后面。最后,rev 将与 x 相反。 32 | 要在没有辅助堆栈 / 数组的帮助下 “弹出” 和 “推入” 数字,我们可以使用数学方法。 33 | //pop operation: 34 | pop = x % 10; 35 | x /= 10; 36 | 37 | //push operation: 38 | temp = rev * 10 + pop; 39 | rev = temp; 40 | 但是,这种方法很危险,因为当 \text{temp} = \text{rev} \cdot 10 + \text{pop} 41 | temp=rev⋅10+pop 时会导致溢出。 42 | 幸运的是,事先检查这个语句是否会导致溢出很容易。 43 | -------------------------------------------------------------------------------- /008.string-to-integer-atoi/008.string-to-integer-atoi.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int myAtoi(string str) { 4 | int n = str.size(); 5 | int i; 6 | int flag = 0; 7 | long ans = 0; 8 | for(i = 0 ; i < n ; i ++){ 9 | if(flag == 0){ 10 | if(str[i] == '+') flag = 1; 11 | else if(str[i] == '-') flag = -1; 12 | else if(str[i] == ' ') continue; 13 | else if(str[i] >= '0' && str[i] <= '9'){ 14 | ans = str[i] - '0'; 15 | flag = 1; 16 | } 17 | else return 0; 18 | } 19 | else{ 20 | if(str[i] >= '0' && str[i] <= '9'){ 21 | ans = ans * 10 + (str[i] - '0'); 22 | if(ans * flag < INT_MIN) return INT_MIN; 23 | if(ans * flag > INT_MAX) return INT_MAX; 24 | } 25 | else if(ans != 0) break; 26 | else return 0; 27 | } 28 | } 29 | return ans * flag; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /008.string-to-integer-atoi/008.string-to-integer-atoi.py: -------------------------------------------------------------------------------- 1 | #方法2(python版本)执行用时: 44 ms 战胜90%提交记录 2 | 3 | class Solution(object): 4 | def myAtoi(self, str): 5 | """ 6 | :type str: str 7 | :rtype: int 8 | """ 9 | # 导入正则模块 10 | import re 11 | # 字符串中查找全部符合条件的整数,返回的是列表,第一个参数是正则,第二个参数是字符串 12 | # strip()字符串去空格 13 | ret = re.findall(r"^[-+]?\d+", str.strip()) 14 | # 判断是否有匹配的值,没有的话返回0,例如"word values 987",匹配不到,返回0 15 | if ret: 16 | ret_str = ret[0] # 匹配的数字的字符串 17 | ret_str2 = "" # 记录去符号的字符串,ret_str后面还要使用,所以定义一个新的变量记录 18 | # 判断是否带有符号 + or - 19 | if ret_str[0] == "-" or ret_str[0] == "+": 20 | ret_str2 = ret_str[1:] 21 | else: 22 | ret_str2 = ret_str 23 | # str转int 24 | ret_int = int(ret_str2) 25 | # 判断第一个字符是否为负号 26 | if ret_str[0] == "-": 27 | # 三目运算符,判断是否溢出 28 | # 如果ret_int <= 2**31则返回-ret_int,否则返回-2**31 29 | return -ret_int if ret_int <= 2**31 else -2**31 30 | else: 31 | return ret_int if ret_int < 2**31 else 2**31-1 32 | else: 33 | return 0 34 | -------------------------------------------------------------------------------- /009.palindrome-number/009.palindrome-number.cs: -------------------------------------------------------------------------------- 1 | // c#版本 2 | 3 | public class Solution { 4 | public bool IsPalindrome(int x) { 5 | // 特殊情况: 6 | // 如上所述,当 x < 0 时,x 不是回文数。 7 | // 同样地,如果数字的最后一位是 0,为了使该数字为回文, 8 | // 则其第一位数字也应该是 0 9 | // 只有 0 满足这一属性 10 | if(x < 0 || (x % 10 == 0 && x != 0)) { 11 | return false; 12 | } 13 | 14 | int revertedNumber = 0; 15 | while(x > revertedNumber) { 16 | revertedNumber = revertedNumber * 10 + x % 10; 17 | x /= 10; 18 | } 19 | 20 | // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。 21 | // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123, 22 | // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。 23 | return x == revertedNumber || x == revertedNumber/10; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /009.palindrome-number/009.palindrome-number.java: -------------------------------------------------------------------------------- 1 | public boolean isPalindrome(int x) { 2 | if (x < 0) { 3 | return false; 4 | } 5 | int n = x; 6 | int tmp = 0; 7 | while (x != 0) { 8 | tmp = tmp * 10 + x % 10; 9 | x = x/10; 10 | } 11 | return n == tmp ? true : false; 12 | } 13 | -------------------------------------------------------------------------------- /009.palindrome-number/009.palindrome-number.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPalindrome(self,x): 3 | """ 4 | :type x: int 5 | :rtype: bool 6 | """ 7 | if(x<0): 8 | return False 9 | n = x; 10 | temp = 0; 11 | while x!=0: 12 | temp = temp * 10 + x%10; 13 | x=x//10; 14 | return n==temp 15 | -------------------------------------------------------------------------------- /010.regular-expression-matching/010.regular-expression-matching.cpp: -------------------------------------------------------------------------------- 1 | //方法3(c++版本)动态规划实现 2 | bool isMatch(string s, string p) { 3 | int lens = s.length(), lenp = p.length(); 4 | bool ** dp = new bool*[lens + 2]; 5 | for (int i = 0; i < lens+2; i++) 6 | dp[i] = new bool[lenp + 2]; 7 | 8 | for (int i = 0; i < lens+2; i++) 9 | for (int j = 0; j < lenp+2; j++) 10 | dp[i][j] = false; 11 | dp[0][0] = true; 12 | 13 | for (int i = 1; i < lenp; i++) 14 | if (p[i] == '*'&&dp[0][i - 1]) 15 | dp[0][i + 1] = true; 16 | 17 | for (int i = 0; i < lens; i++) 18 | for (int j = 0; j < lenp; j++) 19 | { 20 | if (s[i] == p[j] || p[j] == '.') 21 | dp[i + 1][j + 1] = dp[i][j]; 22 | else if (p[j] == '*') 23 | { 24 | if (p[j - 1] != s[i] && p[j - 1] != '.') 25 | dp[i + 1][j + 1] = dp[i + 1][j - 1]; 26 | else 27 | dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j - 1]); 28 | } 29 | } 30 | 31 | 32 | return dp[lens][lenp]; 33 | } 34 | -------------------------------------------------------------------------------- /010.regular-expression-matching/010.regular-expression-matching.py: -------------------------------------------------------------------------------- 1 | def isMatch(self, s, p): 2 | """ 3 | :type s: str 4 | :type p: str 5 | :rtype: bool 6 | """ 7 | # 判断匹配规则是否为空 8 | if p == "": 9 | # p为空的时候,判断s是否为空,则知道返回True 或 False 10 | return s == "" 11 | # 判断匹配规则是否只有一个 12 | if len(p) == 1: 13 | # 判断匹配字符串长度是否为1,和两者的第一个元素是否相同,或匹配规则使用. 14 | return len(s) == 1 and (s[0] == p[0] or p[0] == '.') 15 | # 匹配规则的第二个字符串不为*,当匹配字符串不为空的时候 16 | # 返回 两者的第一个元素是否相同,或匹配规则使用. and 递归新的字符串(去掉第一个字符的匹配字符串 和 去掉第一个字符的匹配规则) 17 | if p[1] != "*": 18 | if s == "": 19 | return False 20 | return (s[0] == p[0] or p[0] == '.') and self.isMatch(s[1:], p[1:]) 21 | # 当匹配字符串不为空 and (两者的第一个元素是否相同 or 匹配规则使用.) 22 | while s and (s[0] == p[0] or p[0] == '.'): 23 | # 到了while循环,说明p[1]为*,所以递归调用匹配s和p[2:](*号之后的匹配规则) 24 | # 用于跳出函数,当s循环到和*不匹配的时候,则开始去匹配p[2:]之后的规则 25 | if self.isMatch(s, p[2:]): 26 | return True 27 | # 当匹配字符串和匹配规则*都能匹配的时候,去掉第一个字符成为新的匹配字符串,循环 28 | s = s[1:] 29 | # 假如第一个字符和匹配规则不匹配,则去判断之后的是否匹配 30 | return self.isMatch(s, p[2:]) 31 | -------------------------------------------------------------------------------- /011.container-with-most-water/011.container-with-most-water.cpp: -------------------------------------------------------------------------------- 1 | //方法4(leetcode版):逼近法 2 | //每次左右两端都舍去短的那一端  3 | //若选择短的那一端【S=小于等于此端的高*小于等于当前的最大区间长度】,至多的面积也是选择最左最右的一个矩形,因此不必再考虑短的一端,直接舍去逼近 4 | 5 | class Solution { 6 | public: 7 | int maxArea(vector& height) { 8 | int _m = 0, r = height.size()-1,l=0; 9 | while (r > l) { 10 | _m = max(_m, min(height[l], height[r])*(r - l)); 11 | if (height[r] > height[l]) ++l; 12 | else --r; 13 | } 14 | return _m; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /011.container-with-most-water/011.container-with-most-water.java: -------------------------------------------------------------------------------- 1 | //方法1(Java版):暴力法 2 | //在这种情况下,我们将简单地考虑每对可能出现的线段组合并找出这些情况之下的最大面积。 3 | 4 | public class Solution { 5 | public int maxArea(int[] height) { 6 | int maxarea = 0; 7 | for (int i = 0; i < height.length; i++) 8 | for (int j = i + 1; j < height.length; j++) 9 | maxarea = Math.max(maxarea, Math.min(height[i], height[j]) * (j - i)); 10 | return maxarea; 11 | } 12 | } 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /011.container-with-most-water/011.container-with-most-water.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxArea(self, height): 3 | """ 4 | :type height: List[int] 5 | :rtype: int 6 | """ 7 | """ 8 | 逼近法 9 | 每次左右两端都舍去短的那一端 10 | 若选择短的那一端【S=小于等于此端的高*小于等于当前的最大区间长度】 11 | 至多的面积也是选择最左最右的一个矩形,因此不必再考虑短的一端,直接舍去逼近 12 | """ 13 | # 记录当前最大容量的面积 14 | max_area = 0 15 | # 记录最左边的下标 16 | left = 0 17 | # 记录右边的下标 18 | right = len(height) - 1 19 | # 当右边下标大于左边下标的时候循环 20 | while right > left: 21 | # 当前循环中最大的容量面积,使用max方法比较上次的max_area和此次的容量面积,取最大值 22 | # min(height[left], height[right]) * (right - left) 取左边和右边的高当中的最小值, 下标right-left为宽,两者相乘为最大面积 23 | max_area = max(max_area, min(height[left], height[right]) * (right - left)) 24 | # 判断哪条高小,小的那边下标进行操作 25 | if height[right] > height[left]: 26 | left += 1 27 | else: 28 | right -= 1 29 | return max_area 30 | -------------------------------------------------------------------------------- /011.container-with-most-water/011.container-with-most-water_2.java: -------------------------------------------------------------------------------- 1 | //方法2(Java版):双指针法 2 | //这种方法背后的思路在于,两线段之间形成的区域总是会受到其中较短那条长度的限制。此外,两线段距离越远,得到的面积就越大。 3 | //我们在由线段长度构成的数组中使用两个指针,一个放在开始,一个置于末尾。 此外,我们会使用变量 maxarea 4 | //maxarea 来持续存储到目前为止所获得的最大面积。 在每一步中,我们会找出指针所指向的两条线段形成的区域,更新 maxarea 5 | //maxarea,并将指向较短线段的指针向较长线段那端移动一步。 6 | 7 | public class Solution { 8 | public int maxArea(int[] height) { 9 | int maxarea = 0, l = 0, r = height.length - 1; 10 | while (l < r) { 11 | maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l)); 12 | if (height[l] < height[r]) 13 | l++; 14 | else 15 | r--; 16 | } 17 | return maxarea; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /011.container-with-most-water/question&solution.md: -------------------------------------------------------------------------------- 1 | Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). 2 | 3 | n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). 4 | 5 | Find two lines, which together with x-axis forms a container, such that the container contains the most water. 6 | 7 | Note: You may not slant the container and n is at least 2. 8 | 9 | ![water](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/Container%20With%20Most%20Water.jpg?raw=true) 10 | 11 | 12 | 13 | `题目 : 盛最多水的容器` 14 | 15 | 给定n个非负整数a 1,a 2,...,a n ,其中每个表示坐标(i,a i)处的点。绘制n条垂直线,使得线i的两个端点位于(i,a i)和(i,0)。找到两条线,它们与x轴一起形成一个容器,这样容器就含有最多的水。 16 | 17 | 注意: 您可能不会倾斜容器,n至少为2。 18 | 19 | ![water](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/Container%20With%20Most%20Water.jpg?raw=true) 20 | 21 | 上面的垂直线由数组[1,8,6,2,5,4,8,3,7]表示。在这种情况下,容器可容纳的最大水面积(蓝色部分)为49。 22 | 23 | 24 | 例: 25 | 26 | 输入: [1,8,6,2,5,4,8,3,7] 27 | 产出: 49 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /012.integer-to-roman/012.integer-to-roman_2.py: -------------------------------------------------------------------------------- 1 | #欢迎关注微信公众号:AI数据分析算法 2 | 3 | #leetcode官网上60ms版本 4 | 5 | UNITS = ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'] 6 | TENS = ['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'] 7 | HUNDREDS = ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'] 8 | THOUSANDS = ['', 'M', 'MM', 'MMM', 'M(V)', '(V)', '(V)M', '(V)MM', '(V)MMM', 'M(X)'] 9 | 10 | class Solution(object): 11 | def intToRoman(self, num): 12 | """ 13 | :type num: int 14 | :rtype: str 15 | """ 16 | 17 | return THOUSANDS[num // 1000] + HUNDREDS[(num // 100) % 10] + TENS[(num // 10) % 10] + UNITS[num % 10] 18 | 19 | 20 | ''' 21 | class Solution: 22 | def intToRoman(self, num): 23 | M = ["", "M", "MM", "MMM"]; 24 | C = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]; 25 | X = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]; 26 | I = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]; 27 | return M[num//1000]+C[(num%1000)//100]+X[(num%100)//10]+I[num%10] 28 | 29 | ''' 30 | -------------------------------------------------------------------------------- /012.integer-to-roman/012.integer-to-roman_by辰星.py: -------------------------------------------------------------------------------- 1 | #欢迎关注微信公众号:AI数据分析算法 2 | #来自群成员 @辰星 的方法 3 | class Solution: 4 | def intToRoman(self,num): 5 | ''' 6 | :type num:int 7 | :rtype:str n4 8 | ''' 9 | rtn='' 10 | conv_tab=(1000,100,10,1) 11 | conv_value={1000:('','M','MM','MMM'),100: 12 | (",'C','CC','CCC','CD','D','DC',"DCC','DCCC','CM'),10: 13 | (",'X','XX','XXX','XL','L','LX','LXX','LXXX','XC'),1: 14 | (",'I','II','III','IV','V','VI','VII','VIII','IX')} 15 | for base in conv_tab: 16 | cnt=num //base 17 | num=num % base 18 | rtn+=conv_value[base][cnt] 19 | return rtn 20 | 21 | -------------------------------------------------------------------------------- /012.integer-to-roman/integer-to-roman_by李振兴.py: -------------------------------------------------------------------------------- 1 | #欢迎关注微信公众号:AI数据分析算法 2 | #本体解法来源于群内成员@李振兴 3 | class Solution(object): 4 | 5 | r = { 6 | # value is an array of strings for each key in 7 | # the ones, tens, hundreds, and thousands places 8 | # up to 3000 (since given max is 3999) 9 | 1: ['I', 'X', 'C', 'M'], 10 | 2: ['II', 'XX', 'CC', 'MM'], 11 | 3: ['III', 'XXX', 'CCC', 'MMM'], 12 | 4: ['IV', 'XL', 'CD'], 13 | 5: ['V', 'L', 'D'], 14 | 6: ['VI', 'LX', 'DC'], 15 | 7: ['VII', 'LXX', 'DCC'], 16 | 8: ['VIII', 'LXXX', 'DCCC'], 17 | 9: ['IX', 'XC', 'CM'] 18 | } 19 | def intToRoman(self,num): 20 | ret = "" 21 | A = map(int,str(num))[::-1] 22 | indexi = 0 23 | for i in A: 24 | ret = r[i][indexi] + ret 25 | indexi +=1 26 | return ret 27 | 28 | 29 | -------------------------------------------------------------------------------- /013.Roman_to_int/013.Roman_to_int.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 根据罗马数字的规则,只有在前面的字母比当前字母小的情况下要执行减法, 3 | 其他情况只需要把罗马字母对应的数字直接相加即可。 4 | 如果发现前一个字母比当前字母小,就减去前一个字母, 5 | 因为错误的把它加入了结果,且在加上当前字母时还要减去前一个字母的值。 6 | 7 | ''' 8 | 9 | class Solution(object): 10 | def romanToInt(self, s): 11 | """ 12 | :type s: str 13 | :rtype: int 14 | """ 15 | map = {"M": 1000, "D": 500, "C": 100, "L": 50, "X": 10, "V": 5, "I": 1} 16 | result = 0 17 | for i in range(len(s)): 18 | if i > 0 and map[s[i]] > map[s[i - 1]]: 19 | result -= map[s[i - 1]] 20 | result += map[s[i]] - map[s[i - 1]] 21 | else: 22 | result += map[s[i]] 23 | return result 24 | 25 | 26 | if __name__ == "__main__": 27 | So = Solution() 28 | print(So.romanToInt("XII")) 29 | print(So().romanToInt("XXI")) 30 | print(So().romanToInt("XCIX")) 31 | -------------------------------------------------------------------------------- /013.Roman_to_int/question&solution.md: -------------------------------------------------------------------------------- 1 | ![Roman_to_int](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/Roman_to_int.png?raw=true) 2 | 3 | 4 | `原题` 5 | 6 | 将一个罗马数字转化为阿拉伯数字,范围在1-3999。下面是罗马数字的介绍及基本规则: 7 | 8 | 罗马数字采用七个罗马字母作数字、即Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。记数的方法: 9 | 10 | 相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3 11 | 12 | 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12 13 | 14 | 小的数字(限于 Ⅰ、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 Ⅳ=4、Ⅸ=9 15 | 16 | `注意点:` 17 | 18 | 输入的罗马数字是符合规范的,不需要考虑错误情况 19 | 20 | `例子:` 21 | 22 | 输入: s="XCIX" 输出: 99 23 | 24 | 25 | `解题思路` 26 | 27 | 根据罗马数字的规则,只有在前面的字母比当前字母小的情况下要执行减法, 28 | 其他情况只需要把罗马字母对应的数字直接相加即可。如果发现前一个字母比当前字母小, 29 | 就减去前一个字母,因为错误的把它加入了结果,且在加上当前字母时还要减去前一个字母的值。 30 | -------------------------------------------------------------------------------- /014.Longest Common Prefix/014.Longest Common Prefix.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Solution { 4 | public: 5 | string longestCommonPrefix(vector &strs) { 6 | if (strs.empty()) 7 | return ""; 8 | for (int i = 0; i < strs[0].length(); i++) { 9 | for (int j = 1; j < strs.size(); j++) 10 | if (i >= strs[j].length() || strs[j][i] != strs[0][i]) 11 | return strs[0].substr(0, i); 12 | } 13 | return strs[0]; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /014.Longest Common Prefix/014.Longest Common Prefix.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | /** 3 | * @param strs: A list of strings 4 | * @return: The longest common prefix 5 | */ 6 | public String longestCommonPrefix(String[] strs) { 7 | if(strs.length == 0){ 8 | return ""; 9 | } 10 | 11 | String prefix = strs[0]; 12 | 13 | for(int i=1;ilen(A1)+len(B1), 24 | 25 | 那么第k个数就不可能在B1,因为比B1的数小的数最多只有B1加上部分的A1,也就是klen(A1)+len(B1),矛盾。 28 | 29 | 同理可以推理出另外两种情况。 30 | -------------------------------------------------------------------------------- /021.merge-two-sorted-lists/012.merge-two-sorted-lists.java: -------------------------------------------------------------------------------- 1 | public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 2 | ListNode helper = new ListNode(0); 3 | ListNode pre = helper; 4 | helper.next = l1; 5 | while(l1!=null && l2 != null) 6 | { 7 | if(l1.val>l2.val) 8 | { 9 | ListNode next = l2.next; 10 | l2.next = pre.next; 11 | pre.next = l2; 12 | l2 = next; 13 | } 14 | else 15 | { 16 | l1 = l1.next; 17 | } 18 | pre = pre.next; 19 | 20 | } 21 | if(l2!=null) 22 | { 23 | pre.next = l2; 24 | } 25 | return helper.next; 26 | } 27 | -------------------------------------------------------------------------------- /021.merge-two-sorted-lists/012.merge-two-sorted-lists.py: -------------------------------------------------------------------------------- 1 | #方法1:(python版本) 2 | #为了避免分类讨论,添加一个假的头节点。现在只需要两个指针分别指向原来的两个链表,将其中比较小的节点添加到新的链表中。 3 | #传入的参数l1和l2正好可以当作遍历两个链表的指针。 4 | 5 | class ListNode(object): 6 | def __init__(self, x): 7 | self.val = x 8 | self.next = None 9 | 10 | 11 | class Solution(object): 12 | def mergeTwoLists(self, l1, l2): 13 | """ 14 | :type l1: ListNode 15 | :type l2: ListNode 16 | :rtype: ListNode 17 | """ 18 | temp = ListNode(-1) 19 | head = temp 20 | while l1 and l2: 21 | if l1.val > l2.val: 22 | temp.next = l2 23 | l2 = l2.next 24 | else: 25 | temp.next = l1 26 | l1 = l1.next 27 | temp = temp.next 28 | if l1: 29 | temp.next = l1 30 | else: 31 | temp.next = l2 32 | return head.next 33 | 34 | 35 | if __name__ == "__main__": 36 | assert Solution().mergeTwoLists(ListNode(1), ListNode(2)).val == 1 37 | -------------------------------------------------------------------------------- /021.merge-two-sorted-lists/question&solution.md: -------------------------------------------------------------------------------- 1 | `题目:merge two sorted lists(将两个有序的链表拼接成一个有序的链表。)` 2 | 3 | 4 | `注意点:` 5 | 6 | 不需要额外申请节点,主要把原链表中的节点串联起来 7 | 原链表中的一个已经全部在新链表中后,另一个链表剩余的部分可以直接拼接 8 | 例子: 9 | 输入: l1 = 1->2->4, l2 = 3 输出: 1->2->3->4 10 | -------------------------------------------------------------------------------- /026.RemoveDuplicates fromSorted Array/026.RemoveDuplicates fromSorted Array.cpp: -------------------------------------------------------------------------------- 1 | #-----------CPP------------ 2 | class Solution { 3 | public: 4 | int removeDuplicates(vector& nums) { 5 | if(nums.size() == 0) 6 | return 0; 7 | 8 | int len; //当前数组中已经筛选出的非重复元素个数 9 | len = 1; //数组第一个元素直接计数 10 | for(int i = 1;i < nums.size();i++){ 11 | if(nums[i] != nums[len - 1]){ //遍历到的非重复值 12 | nums[len] = nums[i]; 13 | ++len; 14 | } 15 | } 16 | return len; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /026.RemoveDuplicates fromSorted Array/026.RemoveDuplicates fromSorted Array.java: -------------------------------------------------------------------------------- 1 | ------------------JAVA----------------------- 2 | class Solution { 3 | public int removeDuplicates(int[] nums) { 4 | if(nums.length == 0){ 5 | return 0; 6 | } 7 | int num = 0; 8 | for (int i = 0; i < nums.length; i++) { 9 | if(nums[num] != nums[i]){ 10 | num++; 11 | nums[num] = nums[i]; 12 | } 13 | } 14 | return ++num; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /026.RemoveDuplicates fromSorted Array/026.RemoveDuplicates fromSorted Array.py: -------------------------------------------------------------------------------- 1 | #-------------PYTHON---------------- 2 | class Solution: 3 | def removeDuplicates(self, nums): 4 | """ 5 | :type nums: List[int] 6 | :rtype: int 7 | """ 8 | if len(nums) <= 1: 9 | return len(nums) 10 | s = 0 11 | for f in range(1, len(nums)): 12 | if nums[s] != nums[f]: 13 | s += 1 14 | nums[s] = nums[f] 15 | return s + 1 16 | -------------------------------------------------------------------------------- /026.RemoveDuplicates fromSorted Array/README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Roman_to_int](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/26.RemoveDuplicates%20fromSorted%20Array.png) 3 | 4 | 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 5 | 6 | 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 7 | 8 | 示例 1: 9 | 10 | 给定数组 nums = [1,1,2], 11 | 12 | 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 13 | 14 | 你不需要考虑数组中超出新长度后面的元素。 15 | 示例 2: 16 | 17 | 给定 nums = [0,0,1,1,1,2,2,3,3,4], 18 | 19 | 函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。 20 | 21 | 你不需要考虑数组中超出新长度后面的元素。 22 | 说明: 23 | 24 | 为什么返回数值是整数,但输出的答案是数组呢? 25 | 26 | 请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 27 | 28 | 你可以想象内部操作如下: 29 | 30 | // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 31 | int len = removeDuplicates(nums); 32 | 33 | // 在函数里修改输入数组对于调用者是可见的。 34 | // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 35 | for (int i = 0; i < len; i++) { 36 | print(nums[i]); 37 | } 38 | -------------------------------------------------------------------------------- /027.Remove Element/027.Remove Element.cpp: -------------------------------------------------------------------------------- 1 | //----------cpp------------ 2 | class Solution { 3 | public: 4 | int removeElement(vector& nums, int val) { 5 | int n = nums.size(), p = 0; 6 | for (int i = 0; i < n; i++) { 7 | if (val != nums[i]) 8 | nums[p++] = nums[i]; 9 | } 10 | return p; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /027.Remove Element/027.Remove Element.java: -------------------------------------------------------------------------------- 1 | 2 | //----------------java-------------------- 3 | public class Solution { 4 | public int removeElement(int[] A, int elem) { 5 | //{1,1,2,1,2,3,2,3,1} 6 | int newIndex = 0; 7 | for (int oldIndex = 0; oldIndex < A.length; ++oldIndex) { 8 | if (A[oldIndex] != elem) { 9 | A[newIndex++] = A[oldIndex]; 10 | } 11 | } 12 | return newIndex; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /027.Remove Element/027.Remove Element.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /027.Remove Element/README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Roman_to_int](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/027.Remove%20Element.jpg) 3 | 4 | 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 5 | 6 | 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 7 | 8 | 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 9 | 10 | 示例 1: 11 | 12 | 给定 nums = [3,2,2,3], val = 3, 13 | 14 | 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 15 | 16 | 你不需要考虑数组中超出新长度后面的元素。 17 | 示例 2: 18 | 19 | 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 20 | 21 | 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。 22 | 23 | 注意这五个元素可为任意顺序。 24 | 25 | 你不需要考虑数组中超出新长度后面的元素。 26 | 说明: 27 | 28 | 为什么返回数值是整数,但输出的答案是数组呢? 29 | 30 | 请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 31 | 32 | 你可以想象内部操作如下: 33 | 34 | // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝 35 | int len = removeElement(nums, val); 36 | 37 | // 在函数里修改输入数组对于调用者是可见的。 38 | // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 39 | for (int i = 0; i < len; i++) { 40 | print(nums[i]); 41 | } 42 | -------------------------------------------------------------------------------- /028.Implement strStr()/028.Implement strStr().cpp: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | public: 4 | int strStr(string haystack, string needle) { 5 | const int n = needle.size(); 6 | const int m = haystack.size(); 7 | int *next = new int[n]; 8 | getNext(needle, next); 9 | int i = 0; 10 | int j = 0; 11 | while (i < m && j < n){ //此处使用needle.size()会出问题。 12 | if (j==-1 || haystack[i] == needle[j]){ 13 | i++; 14 | j++; 15 | } 16 | else 17 | j = next[j]; 18 | } 19 | if (j == n) return i - j; 20 | else 21 | return -1; 22 | } 23 | void getNext(string & needle, int next[]){ 24 | int n = needle.size(); 25 | int k = -1; 26 | int j = 0; 27 | next[0] = -1; 28 | while (j < n - 1){ 29 | if (k == -1 || needle[j] == needle[k]){ 30 | j++; 31 | k++; 32 | next[j] = k; 33 | } 34 | else 35 | k = next[k]; 36 | } 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /028.Implement strStr()/028.Implement strStr().java: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | public int strStr(String haystack, String needle) { 4 | int l1=haystack.length(), 5 | l2=needle.length(); 6 | if(l1 lefts; 6 | 7 | for (int i = 0; i < s.size(); ++i) { 8 | if (s[i] == '(') { 9 | lefts.push(i); 10 | } else { 11 | if (lefts.empty()) { 12 | last = i; 13 | } else { 14 | lefts.pop(); 15 | if (lefts.empty()) { 16 | max_len = max(max_len, i - last); 17 | } else { 18 | max_len = max(max_len, i - lefts.top()); 19 | } 20 | } 21 | } 22 | } 23 | return max_len; 24 | } 25 | }; -------------------------------------------------------------------------------- /032. Longest Valid Parentheses—Dynamic Programming/Longest Valid Parentheses.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int longestValidParentheses(String s) { 3 | if (s == null || s.length() < 2) { 4 | return 0; 5 | } 6 | 7 | int[] dp = new int[s.length()]; 8 | int max = 0; 9 | dp[0] = 0; 10 | for (int i = 1; i < s.length(); i++) { 11 | if (s.charAt(i) == '(') { 12 | continue; 13 | } 14 | int i1 = i - dp[i - 1] - 1; 15 | if (i1 < 0) { 16 | continue; 17 | } 18 | if (s.charAt(i1) == '(') { 19 | int pre = i1 - 1 < 0 ? 0 : i1 - 1; 20 | dp[i] = dp[i - 1] + 2 + dp[pre]; 21 | } 22 | max = Math.max(dp[i], max); 23 | } 24 | 25 | return max; 26 | } 27 | } -------------------------------------------------------------------------------- /032. Longest Valid Parentheses—Dynamic Programming/Longest Valid Parentheses.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 思路:1.使用栈进行操作 3 | 如果是左括号,直接入stack, 4 | 如果右括号,如果stack里没有元素匹对,说明有效括号已经结束,更新起始位置,有元素匹对pop出一个左括号匹对, 5 | 如果此时没了,不能保证不继续有效括号,所以根据当前的最长距离去更新maxlen, 6 | 如果此时还有 则计算与栈顶的索引相减来计算长度。 7 | 8 | ''' 9 | 10 | class Solution: 11 | def longestValidParentheses(self, s): 12 | ans = 0 13 | n = len(s) 14 | stack = [] 15 | st = 0 16 | for i in range(n): 17 | 18 | if s[i] == '(': 19 | stack.append(i) 20 | else: 21 | if len(stack) == 0: 22 | st = i+ 1 23 | continue 24 | else: 25 | stack.pop() 26 | if len(stack) == 0: 27 | ans = max(ans,i - st + 1) 28 | else: 29 | ans = max(ans,i-stack[-1]) 30 | return ans 31 | -------------------------------------------------------------------------------- /032. Longest Valid Parentheses—Dynamic Programming/Readme.md: -------------------------------------------------------------------------------- 1 | Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. 2 | 3 | Example 1: 4 | 5 | Input: "(()" 6 | Output: 2 7 | Explanation: The longest valid parentheses substring is "()" 8 | Example 2: 9 | 10 | Input: ")()())" 11 | Output: 4 12 | Explanation: The longest valid parentheses substring is "()()" -------------------------------------------------------------------------------- /033. Search in Rotated Sorted Array/033. Search in Rotated Sorted Array.cpp: -------------------------------------------------------------------------------- 1 | #解题思路: 2 | #这题要求你的算法时间复杂度必须是 O(log n) 级别。 3 | 4 | #二分搜索法的关键在于获得了中间数后,判断下面要搜索左半段还是右半段,我们观察上面红色加粗的数字都是升序的, 5 | #由此我们可以观察出规律,如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的, 6 | #我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留哪半边了,代码如下 7 | class Solution { 8 | public: 9 | int search(int A[], int n, int target) { 10 | if (n == 0) return -1; 11 | int left = 0, right = n - 1; 12 | while (left <= right) { 13 | int mid = (left + right) / 2; 14 | if (A[mid] == target) return mid; 15 | else if (A[mid] < A[right]) { 16 | if (A[mid] < target && A[right] >= target) left = mid + 1; 17 | else right = mid - 1; 18 | } else { 19 | if (A[left] <= target && A[mid] > target) right = mid - 1; 20 | else left = mid + 1; 21 | } 22 | } 23 | return -1; 24 | } 25 | }; -------------------------------------------------------------------------------- /033. Search in Rotated Sorted Array/033. Search in Rotated Sorted Array.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int search(int[] nums, int target) { 3 | //实际上就是两个递增序列,依旧是二分法 4 | //只不过只在递增序列中二分 5 | if(nums.length==0){ 6 | return -1; 7 | } 8 | int st = 0,end = nums.length-1; 9 | while(st <= end){ 10 | int mid = st+(end-st)/2; 11 | if(nums[mid]==target){ 12 | return mid; 13 | } 14 | if(nums[mid]>=nums[st]){ 15 | if(nums[st]<=target&&target nums[r]: 14 | l = mid + 1 15 | else: 16 | r = mid 17 | pol = l 18 | ans = self.binary_search(target, nums[:pol]) 19 | if ans == -1: 20 | ans = self.binary_search(target, nums[pol:]) 21 | if ans != -1: 22 | ans += len(nums[:pol]) 23 | 24 | return ans 25 | 26 | def binary_search(self, target, nums): 27 | index = -1 28 | l = 0 29 | r = len(nums) - 1 30 | while l <= r: 31 | mid = (l+r)//2 32 | if nums[mid] < target: 33 | l = mid + 1 34 | elif nums[mid] > target: 35 | r = mid - 1 36 | else: 37 | index = mid 38 | break 39 | return index 40 | -------------------------------------------------------------------------------- /033. Search in Rotated Sorted Array/Readme.txt: -------------------------------------------------------------------------------- 1 | 33. Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. 2 | 3 | (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). 4 | 5 | You are given a target value to search. If found in the array return its index, otherwise return -1. 6 | 7 | You may assume no duplicate exists in the array. 8 | 9 | Your algorithm's runtime complexity must be in the order of O(log n). 10 | 11 | Example 1: 12 | 13 | Input: nums = [4,5,6,7,0,1,2], target = 0 14 | Output: 4 15 | Example 2: 16 | 17 | Input: nums = [4,5,6,7,0,1,2], target = 3 18 | Output: -1 19 | 33. 搜索旋转排序数组 20 | 21 | 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 22 | 23 | ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 24 | 25 | 搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 26 | 27 | 你可以假设数组中不存在重复的元素。 28 | 29 | 你的算法时间复杂度必须是 O(log n) 级别。 30 | 31 | 示例 1: 32 | 33 | 输入: nums = [4,5,6,7,0,1,2], target = 0 34 | 输出: 4 35 | 示例 2: 36 | 37 | 输入: nums = [4,5,6,7,0,1,2], target = 3 38 | 输出: -1 -------------------------------------------------------------------------------- /035.Search Insert Position/035.Search Insert Position.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | public: 4 | int searchInsert(vector& nums, int target) { 5 | int l=0,r=nums.size()-1,pos=0,mid; 6 | while(l<=r){ 7 | mid=(l+r)>>1; 8 | if(nums[mid]==target)return mid; 9 | else if(target target) 5 | return 0; 6 | if(nums[nums.length - 1] < target) 7 | return nums.length; 8 | //先二分查找,找到了就返回 9 | int low = 0; 10 | int hight = nums.length - 1; 11 | int mid = 0; 12 | while(low <= hight){ 13 | mid = (low + hight)/2; 14 | if(nums[mid] < target){ 15 | low = mid + 1; 16 | }else if(nums[mid] > target){ 17 | hight = mid - 1; 18 | }else{ 19 | return mid; 20 | } 21 | } 22 | //找不到再判断与nums[mid]大小,返回索引 23 | return nums[mid] > target?mid:mid+1; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /035.Search Insert Position/035.Search Insert Position.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A, a list of integers 3 | # @param target, an integer to be inserted 4 | # @return integer 5 | def searchInsert(self, A, target): 6 | left = 0; right = len(A) - 1 7 | while left <= right: 8 | mid = ( left + right ) / 2 9 | if A[mid] < target: 10 | left = mid + 1 11 | elif A[mid] > target: 12 | right = mid - 1 13 | else: 14 | return mid 15 | return left 16 | -------------------------------------------------------------------------------- /035.Search Insert Position/README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Roman_to_int](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/035.Search%20Insert%20Position.jpg) 3 | 4 | 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 5 | 6 | 你可以假设数组中无重复元素。 7 | 8 | 示例 1: 9 | 10 | 输入: [1,3,5,6], 5 11 | 输出: 2 12 | 示例 2: 13 | 14 | 输入: [1,3,5,6], 2 15 | 输出: 1 16 | 示例 3: 17 | 18 | 输入: [1,3,5,6], 7 19 | 输出: 4 20 | 示例 4: 21 | 22 | 输入: [1,3,5,6], 0 23 | 输出: 0 24 | -------------------------------------------------------------------------------- /038. Count and Say/Count and Say.cpp: -------------------------------------------------------------------------------- 1 | //算法很简单,就是对于前一个数,找出相同元素的个数,把个数和该元素存到新的string里。 2 | class Solution { 3 | public: 4 | string countAndSay(int n) { 5 | if (n <= 0) return ""; 6 | string res = "1"; 7 | while (--n) { 8 | string cur = ""; 9 | for (int i = 0; i < res.size(); ++i) { 10 | int cnt = 1; 11 | while (i + 1 < res.size() && res[i] == res[i + 1]) { 12 | ++cnt; 13 | ++i; 14 | } 15 | cur += to_string(cnt) + res[i]; 16 | } 17 | res = cur; 18 | } 19 | return res; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /038. Count and Say/Count and Say.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public String countAndSay(int n) { 3 | if(n == 1){ 4 | return "1"; 5 | } 6 | //递归调用,然后对字符串处理 7 | String str = countAndSay(n-1) + "*";//为了str末尾的标记,方便循环读数 8 | char[] c = str.toCharArray(); 9 | int count = 1; 10 | String s = ""; 11 | for(int i = 0; i < c.length - 1;i++){ 12 | if(c[i] == c[i+1]){ 13 | count++;//计数增加 14 | }else{ 15 | s = s + count + c[i];//上面的*标记这里方便统一处理 16 | count = 1;//初始化 17 | } 18 | } 19 | return s; 20 | } 21 | } 22 | 23 | ! 24 | -------------------------------------------------------------------------------- /038. Count and Say/Count and Say_2.py: -------------------------------------------------------------------------------- 1 | # 群友 @李振业 的方法 2 | def Next(s): 3 | st="1 4 | for i in range(len(s)): 5 | if i!=0 and s[i]==s[i-1]: 6 | pass 7 | else: count=1 8 | while i+count < len(s) and s[i]==s[i+ count]: 9 | count+=1 10 | st += str(count)+s[i] 11 | return st 12 | 13 | s = '1' 14 | n = 6 15 | for i in range(1,n): 16 | s = Next(s) 17 | print s 18 | 19 | -------------------------------------------------------------------------------- /038. Count and Say/Readme.md: -------------------------------------------------------------------------------- 1 | The count-and-say sequence is the sequence of integers with the first five terms as following: 2 | 3 | 1. 1 4 | 2. 11 5 | 3. 21 6 | 4. 1211 7 | 5. 111221 8 | 1 is read off as "one 1" or 11. 9 | 11 is read off as "two 1s" or 21. 10 | 21 is read off as "one 2, then one 1" or 1211. 11 | 12 | Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence. 13 | 14 | Note: Each term of the sequence of integers will be represented as a string. 15 | 16 | 17 | 18 | Example 1: 19 | 20 | Input: 1 21 | Output: "1" 22 | Example 2: 23 | 24 | Input: 4 25 | Output: "1211" 26 | 27 | 28 | `原题` 29 | 30 | 把一个数字用几个几的形式表示出来。如2就是1个2,即12。对12进行数数得到1112,依次类推。 31 | 假设初始数字是1,求第n个数是什么。起始5个数字为1, 11, 21, 1211, 111221, ... 32 | 33 | `注意点:` 34 | 35 | 题目中的数字都用字符串表 36 | 37 | `例子:` 38 | 39 | 输入: n = 5 输出: 111221 40 | 41 | 42 | 43 | `解题思路` 44 | 用一个下标来表示当前统计的字符的起始位置,一个计数器来表示该字符的数目。 45 | 不断读取直到字符不相等,添加到结果集中,更新起始位置和计数器。 46 | 下面代码中的计数器用下标相减代替。 47 | -------------------------------------------------------------------------------- /038. Count and Say/count and say.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 用一个下标来表示当前统计的字符的起始位置,一个计数器来表示该字符的数目。 3 | 不断读取直到字符不相等,添加到结果集中,更新起始位置和计数器。下面代码中的计数器用下标相减代替。 4 | ''' 5 | 6 | class Solution(object): 7 | def countAndSay(self, n): 8 | """ 9 | :type n: int 10 | :rtype: str 11 | """ 12 | result = "1" 13 | for __ in range(1, n): 14 | result = self.getNext(result) 15 | return result 16 | 17 | def getNext(self, s): 18 | result = [] 19 | start = 0 20 | while start < len(s): 21 | curr = start + 1 22 | while curr < len(s) and s[start] == s[curr]: 23 | curr += 1 24 | result.extend((str(curr - start), s[start])) 25 | start = curr 26 | return "".join(result) 27 | 28 | 29 | if __name__ == "__main__": 30 | assert Solution().countAndSay(4) == "1211" 31 | assert Solution().countAndSay(5) == "111221" 32 | -------------------------------------------------------------------------------- /039. Combination Sum/Combination Sum.java: -------------------------------------------------------------------------------- 1 | //采用深度优先搜索的思想+回溯(可以不排序,并去掉剪枝) 2 | 3 | public List> combinationSum(int[] candidates, int target) { 4 | List> res = new ArrayList>(); 5 | List tmp = new ArrayList<>(); 6 | // 排序可以避免重复,结果可以按照顺序输出 7 | Arrays.sort(candidates); 8 | dfsCore(res, 0, 0, tmp, candidates, target); 9 | return res; 10 | } 11 | 12 | private void dfsCore(List> res, 13 | int curIdx, int sum, List tmp, int[] candidates, 14 | int target) { 15 | if (sum > target) 16 | return; 17 | if (sum == target) { 18 | res.add(new ArrayList(tmp)); 19 | return; 20 | } 21 | for (int i = curIdx; i < candidates.length; i++) { 22 | // 剪枝,可以没有,目的为了优化,必须先排序 23 | if (target < candidates[i]) 24 | return; 25 | sum += candidates[i]; 26 | // 剪枝,可以没有,目的为了优化,必须先排序 27 | if (target < sum) 28 | return; 29 | 30 | tmp.add(candidates[i]); 31 | // 之所以不传i+1的原因是: 32 | // The same repeated number may be 33 | // chosen from C unlimited number of time 34 | dfsCore(res, i, sum, tmp, candidates, target); 35 | tmp.remove(tmp.size() - 1); 36 | // 回溯 37 | sum -= candidates[i]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /039. Combination Sum/Combination Sum.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 采用回溯法。由于组合中的数字要按序排列,我们先将集合中的数排序。依次把数字放入组合中, 3 | 因为所有数都是正数,如果当前和已经超出目标值,则放弃;如果和为目标值,则加入结果集; 4 | 如果和小于目标值,则继续增加元素。 5 | 由于结果集中不允许出现重复的组合,所以增加元素时只增加当前元素及之后的元素。 6 | ''' 7 | 8 | class Solution(object): 9 | def combinationSum(self, candidates, target): 10 | """ 11 | :type candidates: List[int] 12 | :type target: int 13 | :rtype: List[List[int]] 14 | """ 15 | if not candidates: 16 | return [] 17 | candidates.sort() 18 | result = [] 19 | self.combination(candidates, target, [], result) 20 | return result 21 | 22 | def combination(self, candidates, target, current, result): 23 | s = sum(current) if current else 0 24 | if s > target: 25 | return 26 | elif s == target: 27 | result.append(current) 28 | return 29 | else: 30 | for i, v in enumerate(candidates): 31 | self.combination(candidates[i:], target, current + [v], result) 32 | 33 | 34 | if __name__ == "__main__": 35 | assert Solution().combinationSum([2, 3, 6, 7], 7) == [[2, 2, 3], [7]] 36 | -------------------------------------------------------------------------------- /039. Combination Sum/Readme.md: -------------------------------------------------------------------------------- 1 | Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. 2 | 3 | The same repeated number may be chosen from candidates unlimited number of times. 4 | 5 | Note: 6 | 7 | All numbers (including target) will be positive integers. 8 | The solution set must not contain duplicate combinations. 9 | Example 1: 10 | 11 | Input: candidates = [2,3,6,7], target = 7, 12 | A solution set is: 13 | [ 14 | [7], 15 | [2,2,3] 16 | ] 17 | Example 2: 18 | 19 | Input: candidates = [2,3,5], target = 8, 20 | A solution set is: 21 | [ 22 | [2,2,2,2], 23 | [2,3,3], 24 | [3,5] 25 | ] 26 | 27 | 28 | `原题` 29 | 30 | 在一个集合(没有重复数字)中找到和为特定值的所有组合。 31 | 32 | `注意点:` 33 | 34 | 所有数字都是正数 35 | 组合中的数字要按照从小到大的顺序 36 | 原集合中的数字可以出现重复多次 37 | 结果集中不能够有重复的组合 38 | 虽然是集合,但传入的参数类型是列表 39 | 40 | `例子:` 41 | 42 | 输入: candidates = [2, 3, 6, 7], target = 7 43 | 输出: [[2, 2, 3], [7]] 44 | -------------------------------------------------------------------------------- /040. Combination Sum II/Combination Sum II.java: -------------------------------------------------------------------------------- 1 | 2 | public List> combinationSum2(int[] candidates, int target) { 3 | List> res = new ArrayList>(); 4 | List tmp = new ArrayList<>(); 5 | // 此题必须先排序 6 | Arrays.sort(candidates); 7 | dfsCore(res, 0, 0, tmp, candidates, target); 8 | return res; 9 | } 10 | 11 | private void dfsCore(List> res, int curIdx, int sum, List tmp, int[] candidates, 12 | 13 | int target) { 14 | 15 | if (sum > target) 16 | return; 17 | if (sum == target) { 18 | res.add(new ArrayList(tmp)); 19 | return; 20 | } 21 | //i = curIdx往后走,避免重复 22 | for (int i = curIdx; i < candidates.length; i++) { 23 | // 如果此层,下一个数跟当前数相等,则直接跳过, 24 | if (i > curIdx && candidates[i] == candidates[i - 1]) 25 | 26 | continue; 27 | // 剪枝,可以没有,目的为了优化,必须先排序 28 | if (target < candidates[i]) 29 | return; 30 | sum += candidates[i]; 31 | // 剪枝,可以没有,目的为了优化,必须先排序 32 | if (target < sum) 33 | return; 34 | 35 | tmp.add(candidates[i]); 36 | // 传入i+1 37 | dfsCore(res, i + 1, sum, tmp, candidates, target); 38 | tmp.remove(tmp.size() - 1); 39 | // 回溯 40 | sum -= candidates[i]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /040. Combination Sum II/Readme.md: -------------------------------------------------------------------------------- 1 | Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. 2 | 3 | Each number in candidates may only be used once in the combination. 4 | 5 | Note: 6 | 7 | All numbers (including target) will be positive integers. 8 | The solution set must not contain duplicate combinations. 9 | Example 1: 10 | 11 | Input: candidates = [10,1,2,7,6,1,5], target = 8, 12 | A solution set is: 13 | [ 14 | [1, 7], 15 | [1, 2, 5], 16 | [2, 6], 17 | [1, 1, 6] 18 | ] 19 | Example 2: 20 | 21 | Input: candidates = [2,5,2,1,2], target = 5, 22 | A solution set is: 23 | [ 24 | [1,2,2], 25 | [5] 26 | ] 27 | 28 | 29 | `原题` 30 | 31 | 在一个数组(存在重复值)中寻找和为特定值的组合。 32 | 33 | `注意点:` 34 | 35 | 所有数字都是正数 36 | 组合中的数字要按照从小到大的顺序 37 | 原数组中的数字只可以出现一次 38 | 结果集中不能够有重复的组合 39 | 40 | `例子:` 41 | 42 | `输入:` candidates = [10, 1, 2, 7, 6, 1, 5], target = 8 43 | `输出: `[[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]] 44 | -------------------------------------------------------------------------------- /045.Jump Game II/Jump Game II.cpp: -------------------------------------------------------------------------------- 1 | ----------------C++-------------这是运行速度最快的 ,大牛写的 ,看不懂 不会c [囧] 2 | static const auto init = []() { 3 | std::ios::sync_with_stdio(false); 4 | std::cin.tie(nullptr); 5 | return nullptr; 6 | }(); 7 | class Solution { 8 | public: 9 | int uniquePaths(int m, int n) { 10 | if (m == 1 || n == 1) 11 | return 1; 12 | vector> p; 13 | for (int i = 0; i < m; i++) 14 | { 15 | vector vec(n); 16 | p.push_back(vec); 17 | } 18 | p[0][0] = 0; 19 | p[1][0] = 1; 20 | p[0][1] = 1; 21 | //p[1][1] = 0; 22 | for (int i = 0; i < n; i++) 23 | { 24 | p[0][i] = 1; 25 | } 26 | for (int i = 0; i < m; i++) 27 | { 28 | p[i][0] = 1; 29 | } 30 | for (int i = 1; i < m; i++) 31 | { 32 | for (int j = 1; j < n; j++) 33 | { 34 | p[i][j] = p[i - 1][j] + p[i][j - 1]; 35 | } 36 | } 37 | return p[m - 1][n - 1]; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /045.Jump Game II/Jump Game II.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int uniquePaths(int m, int n) { 3 | int dp[][]=new int[m][n]; 4 | for(int i=0;i> permute(int[] num) { 12 | ArrayList> res = new ArrayList>(); 13 | ArrayList item = new ArrayList(); 14 | 15 | if(num.length==0||num==null) 16 | return res; 17 | boolean[] visited = new boolean[num.length]; 18 | 19 | permutation_helper(num,res,item,visited); 20 | return res; 21 | } 22 | 23 | public void permutation_helper(int[] num, ArrayList> res, ArrayList item,boolean[] visited){ 24 | if(item.size()==num.length){ 25 | res.add(new ArrayList(item)); 26 | return; 27 | } 28 | 29 | for(int i = 0; i= 0 && s[right] == ' ') --right; 10 | while (right >= 0 && s[right] != ' ' ) { 11 | --right; 12 | ++res; 13 | } 14 | return res; 15 | } 16 | }; -------------------------------------------------------------------------------- /058. Length of Last Word/58. Length of Last Word.java: -------------------------------------------------------------------------------- 1 | /** 2 | 方法来源:https://blog.csdn.net/mikuluna/article/details/84347221 3 | 直接先去两边空格,然后倒叙,如果不是空格,则count++; 4 | 如果是空格,就直接退出循环。最后这个count就是单词长度 5 | 6 | */ 7 | class Solution { 8 | public int lengthOfLastWord(String s) { 9 | int len = s.length(); 10 | s = s.trim(); 11 | int count = 0; 12 | for(int i = s.length() - 1;i >= 0; i--){ 13 | if(s.charAt(i) != ' '){ 14 | count++; 15 | }else { 16 | break; 17 | } 18 | } 19 | return count; 20 | } 21 | } -------------------------------------------------------------------------------- /058. Length of Last Word/58. Length of Last Word.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def lengthOfLastWord(self, s): 3 | if len(s) == 0 : return 0 4 | words = s.split(" ") 5 | count = 0 6 | for i in words: 7 | if not i == '': 8 | count = len(i) 9 | return count -------------------------------------------------------------------------------- /058. Length of Last Word/readme.md: -------------------------------------------------------------------------------- 1 | #### [58. 最后一个单词的长度](https://leetcode-cn.com/problems/length-of-last-word/) 2 | 3 | 4 | 5 | Given a string *s* consists of upper/lower-case alphabets and empty space characters `' '`, return the length of last word in the string. 6 | 7 | If the last word does not exist, return 0. 8 | 9 | **Note:** A word is defined as a character sequence consists of non-space characters only. 10 | 11 | **Example:** 12 | 13 | ``` 14 | Input: "Hello World" 15 | Output: 5 16 | ``` 17 | 18 | ------ 19 | 20 | 给定一个仅包含大小写字母和空格 `' '` 的字符串,返回其最后一个单词的长度。 21 | 22 | 如果不存在最后一个单词,请返回 0 。 23 | 24 | **说明:**一个单词是指由字母组成,但不包含任何空格的字符串。 25 | 26 | **示例:** 27 | 28 | ``` 29 | 输入: "Hello World" 30 | 输出: 5 31 | ``` 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /060. Permutation Sequence/60. Permutation Sequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int calFactorial(int n){ 4 | int ans = 1; 5 | for(int i = 1; i <= n; i++) 6 | ans *= i; 7 | return ans; 8 | } 9 | 10 | string getPermutation(int n, int k) { 11 | string ans; 12 | int num = k; 13 | string s; 14 | int factorial = calFactorial(n); 15 | 16 | for(int i = 0; i < n; i++) 17 | s += '1' + i; 18 | for(int i = n; i > 0; i--){ 19 | factorial /= i; 20 | int index = (num-1) / factorial; 21 | ans += s[index]; 22 | num -= index * factorial; 23 | s.erase(index,1); 24 | } 25 | return ans; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /060. Permutation Sequence/60. Permutation Sequence.java: -------------------------------------------------------------------------------- 1 | //相当于因式分解 2 | public String getPermutation(int n, int k) { 3 | int[] factorial = new int[n]; 4 | 5 | //因式分解需要的基数 6 | for (int i = 0; i < n; i++) { 7 | if (i == 0) { 8 | factorial[i] = 1; 9 | continue; 10 | } 11 | factorial[i] = factorial[i - 1] * (i); 12 | } 13 | //1,1,2,6,24 14 | //1*0+1*1+2*2+6*3+24*4=119 15 | //而我们实际需要的数是:1、2、3、4、5,但他们的组合序列就相当于0、1、2、3、4的组合,只是各自加1而已。 16 | //二者的不同还在于,0-4的k的表是范围是从0-119,而我们的k是从1-120,所以变换关系是k-1。 17 | 18 | 19 | StringBuilder res = new StringBuilder(); 20 | boolean[] used = new boolean[n]; 21 | int i = n - 1; 22 | while (i >= 0) { 23 | int digit = (k - 1) / factorial[i];//变换关系k-1 24 | res.append(findKth(used, digit));//先取最高位的值 25 | k -= digit * factorial[i--]; 26 | } 27 | 28 | return res.toString(); 29 | } 30 | //再次强调下,数组是用的地址,而我们传递的对象就是普通的参数 31 | public int findKth(boolean[] used, int digit) { 32 | int res = -1; 33 | while (digit >= 0) { 34 | if (!used[++res]) { //从小到大的去取值,同时进行标记 35 | digit--; 36 | } 37 | } 38 | used[res] = true; 39 | return res + 1;//从0-4,变为1-5 40 | 41 | } 42 | -------------------------------------------------------------------------------- /060. Permutation Sequence/60. Permutation Sequence.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def getPermutation(self, n, k): 3 | """ 4 | :type n: int 5 | :type k: int 6 | :rtype: str 7 | """ 8 | #0的阶乘一直到9! 9 | #因为题目说了n<=9 10 | self.fac = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880] 11 | #找到对应的n应该对应的fac坐标,就是在第一项确定的情况一下,有(n-1)!种组合 12 | i = n - 1 13 | #构建序列,这个num是用来储存我们当前可以添加的数的,也是为避免重复 14 | num = list(range(1, n+1)) 15 | ret = "" 16 | while i >= 0: 17 | #a用来获得我们要求的那一位在num里的下标 18 | a, b = k // self.fac[i], k % self.fac[i] 19 | #如果刚好整除干净,证明还在上一层 20 | if b == 0: 21 | a -= 1 22 | 23 | 24 | if a >= 0: 25 | ret += str(num[a]) 26 | del num[a] 27 | i -= 1 28 | k = b 29 | #如果刚好整除完,则我们已经可以知道接下来的排序情况了,它一定是最大的 30 | #所以把剩下的可选的数字reverse来制造这种效果 31 | if b == 0: 32 | for i in reversed(num): 33 | ret += str(i) 34 | break 35 | return ret 36 | -------------------------------------------------------------------------------- /062. Unique Paths—Dynamic Programming/Unique Paths.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int uniquePaths(int m, int n) { 4 | vector> info(n,vector(m,0)); 5 | for(int i=0;i Right -> Down -> Down 28 | 2. Down -> Down -> Right -> Right -------------------------------------------------------------------------------- /063. Unique Paths II—Dynamic Programming/Unique Paths II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int uniquePathsWithObstacles(vector>& obstacleGrid) { 4 | int m = obstacleGrid.size(); //行数 5 | int n = obstacleGrid[0].size();//列数 6 | int p[m][n]; 7 | 8 | //第一列赋值 9 | int k = 0; 10 | while(k < m && obstacleGrid[k][0] != 1) 11 | p[k++][0] = 1; 12 | //如果遇到了障碍物则它及其后面的值都为0 13 | while(k < m) 14 | p[k++][0] = 0; 15 | 16 | //第一行赋值 17 | k = 0; 18 | while(k < n && obstacleGrid[0][k] != 1) 19 | p[0][k++] = 1; 20 | while(k < n) 21 | p[0][k++] = 0; 22 | 23 | for(int i = 1; i < m; i++) 24 | for(int j = 1; j < n; j++){ 25 | if(obstacleGrid[i][j] == 1) //如果遇到障碍物,则该位置的值为0 26 | p[i][j] = 0; 27 | else 28 | p[i][j] = p[i - 1][j] + p[i][j - 1]; 29 | } 30 | return p[m-1][n-1]; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /063. Unique Paths II—Dynamic Programming/Unique Paths II.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int uniquePathsWithObstacles(int[][] obstacleGrid) { 3 | if(obstacleGrid[0][0] == 1 || obstacleGrid[obstacleGrid.length-1][obstacleGrid[0].length-1] == 1) 4 | return 0; 5 | int[][] ways = new int[obstacleGrid.length][obstacleGrid[0].length]; 6 | int i = 0; 7 | int j = 0; 8 | for (i = 0; i < obstacleGrid.length; i++) { 9 | for (j = 0; j < obstacleGrid[0].length; j++) { 10 | if (obstacleGrid[i][j] == 1) { 11 | ways[i][j] = 0; 12 | } else if (i == 0 && j == 0) { 13 | ways[i][j] = 1; 14 | } else if (i == 0 && j > 0) { 15 | ways[i][j] = ways[i][j - 1]; 16 | } else if (j == 0 && i > 0) { 17 | ways[i][j] = ways[i - 1][j]; 18 | } else { 19 | ways[i][j] = ways[i - 1][j] + ways[i][j - 1]; 20 | } 21 | 22 | } 23 | } 24 | return ways[i - 1][j - 1]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /063. Unique Paths II—Dynamic Programming/Unique Paths II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def uniquePathsWithObstacles(self, obstacleGrid): 3 | """ 4 | :type obstacleGrid: List[List[int]] 5 | :rtype: int 6 | """ 7 | if not len(obstacleGrid) or not len(obstacleGrid[0]): return 0 8 | m, n = len(obstacleGrid), len(obstacleGrid[0]) 9 | dp = [[0] * (n+1) for _ in xrange(m+1)] 10 | dp[0][1] = 1 11 | for r in xrange(1, m+1): 12 | for c in xrange(1, n+1): 13 | if obstacleGrid[r-1][c-1] == 0: 14 | dp[r][c] = dp[r-1][c] + dp[r][c-1] 15 | return dp[-1][-1] 16 | -------------------------------------------------------------------------------- /064. Minimum Path Sum—Dynamic Programming/Readme.md: -------------------------------------------------------------------------------- 1 | 64. Minimum Path Sum 2 | 3 | Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. 4 | 5 | Note: You can only move either down or right at any point in time. 6 | 7 | Example: 8 | 9 | Input: 10 | [ 11 | [1,3,1], 12 | [1,5,1], 13 | [4,2,1] 14 | ] 15 | Output: 7 16 | Explanation: Because the path 1→3→1→1→1 minimizes the sum. -------------------------------------------------------------------------------- /067. Add Binary/067. Add Binary.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string addBinary(string a, string b) { 4 | string res = ""; 5 | int carry = 0;//进位 6 | int i = a.size()-1, j = b.size()-1; 7 | while(i>=0 || j>=0 || carry==1) 8 | { 9 | int sum = carry; 10 | if(i>=0) 11 | sum += (a[i--]-'0'); 12 | if(j>=0) 13 | sum += (b[j--]-'0'); 14 | res = to_string(sum%2) + res; 15 | carry = sum/2; 16 | } 17 | return res; 18 | } 19 | }; -------------------------------------------------------------------------------- /067. Add Binary/067. Add Binary.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def lengthOfLastWord(self, s): 3 | if len(s) == 0 : return 0 4 | words = s.split(" ") 5 | count = 0 6 | for i in words: 7 | if not i == '': 8 | count = len(i) 9 | return count -------------------------------------------------------------------------------- /067. Add Binary/readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | #### [67. 二进制求和](https://leetcode-cn.com/problems/add-binary/) 4 | 5 | 难度简单 6 | 7 | 给定两个二进制字符串,返回他们的和(用二进制表示)。 8 | 9 | 输入为**非空**字符串且只包含数字 `1` 和 `0`。 10 | 11 | **示例 1:** 12 | 13 | ``` 14 | 输入: a = "11", b = "1" 15 | 输出: "100" 16 | ``` 17 | 18 | **示例 2:** 19 | 20 | ``` 21 | 输入: a = "1010", b = "1011" 22 | 输出: "10101" 23 | ``` 24 | 25 | 68. Add Binary 26 | 27 | Easy 28 | 29 | Given two binary strings, return their sum (also a binary string). 30 | 31 | The input strings are both **non-empty** and contains only characters `1`or `0`. 32 | 33 | **Example 1:** 34 | 35 | ``` 36 | Input: a = "11", b = "1" 37 | Output: "100" 38 | ``` 39 | 40 | **Example 2:** 41 | 42 | ``` 43 | Input: a = "1010", b = "1011" 44 | Output: "10101" 45 | ``` -------------------------------------------------------------------------------- /067.Add Binary 二进制数相加/067.Add Binary 二进制数相加.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int countSubstrings(string s) { 4 | int count = 0; 5 | for (int i = 1; i <= s.size(); i++) { 6 | for (int j = 0; j <= s.size() - i; j++) { 7 | string temp = s.substr(j, i); 8 | string re_temp = temp; 9 | reverse(re_temp.begin(), re_temp.end()); 10 | if (temp == re_temp) { 11 | count++; 12 | } 13 | } 14 | } 15 | return count; 16 | } 17 | }; -------------------------------------------------------------------------------- /069. Sqrt(x)/069. Sqrt(x).cpp: -------------------------------------------------------------------------------- 1 | class Solution_2 { 2 | public: 3 | int mySqrt(int x) { 4 | if (x == 0 || x == 1) 5 | return x; 6 | int i = 0; 7 | int j = x; 8 | int mid; 9 | while (1) 10 | { 11 | mid = (i + j) / 2; 12 | if (mid>x / mid) 13 | j = mid; 14 | else 15 | { 16 | if ((mid + 1) > x / (mid + 1)) 17 | return mid; 18 | i = mid; 19 | } 20 | } 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /069. Sqrt(x)/069. Sqrt(x).java: -------------------------------------------------------------------------------- 1 | //二分法搜索 2 | 3 | class Solution { 4 | public: 5 | int mySqrt(int x) { 6 | if (x<=1) return x; 7 | int l=0,r=x; 8 | while(l<=r){ 9 | int mid=l+(r-l)/2; 10 | if(x/mid>mid) l=mid+1; 11 | else if(x/midx: 12 | r=(r+x/r)/2 13 | return r 14 | 15 | 16 | #思路二 17 | class Solution(object): 18 | def mySqrt(self, x): 19 | """ 20 | :type x: int 21 | :rtype: int 22 | """ 23 | if x==0 or x==1: 24 | return x 25 | i=0 26 | j=x 27 | mid=0 28 | while True: 29 | mid=(i+j)/2 30 | if mid>x/mid: 31 | j=mid 32 | else: 33 | if (mid+1)>x/(mid+1): 34 | return mid 35 | i=mid 36 | -------------------------------------------------------------------------------- /069. Sqrt(x)/reademe.md: -------------------------------------------------------------------------------- 1 | Implement int sqrt(int x). 2 | 3 | Compute and return the square root of x, where x is guaranteed to be a non-negative integer. 4 | 5 | Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned. 6 | 7 | Example 1: 8 | 9 | Input: 4 10 | 11 | Output: 2 12 | 13 | Example 2: 14 | 15 | Input: 8 16 | 17 | Output: 2 18 | 19 | Explanation: The square root of 8 is 2.82842..., and since 20 | the decimal part is truncated, 2 is returned. 21 | 22 | 23 | 原题 24 | 求一个数的平方根。 25 | 注意点: 26 | 27 | 结果返回整数,舍去小数,不是四舍五入 28 | 例子: 29 | 30 | 输入: x = 5 31 | 输出: 2 32 | -------------------------------------------------------------------------------- /070. Climbing Stairs/070. Climbing Stairs.cpp: -------------------------------------------------------------------------------- 1 | //f(n)=f(n-1)+f(n-2)。自底向上 2 | //典型的菲波那切数列 3 | 4 | class Solution { 5 | public: 6 | int climbStairs(int n) { 7 | int a[n + 1]; 8 | a[0] = 1; 9 | a[1] = 1; 10 | 11 | for(int i = 2; i <= n; ++i) 12 | { 13 | a[i] = a[i - 1] + a[i - 2]; 14 | } 15 | 16 | return a[n]; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /070. Climbing Stairs/070. Climbing Stairs.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 这道题就是经典的讲解最简单的DP问题的问题。。 4 | 5 | 假设梯子有n层,那么如何爬到第n层呢,因为每次只能怕1或2步,那么爬到第n层的方法要么是从第n-1层一步上来的,要不就是从n-2层2步上来的,所以递推公式非常容易的就得出了: 6 | 7 | dp[n] = dp[n-1] + dp[n-2] 8 | 9 | 如果梯子有1层或者2层,dp[1] = 1, dp[2] = 2,如果梯子有0层,自然dp[0] = 0 10 | */ 11 | public int climbStairs(int n) { 12 | if(n==0||n==1||n==2) 13 | return n; 14 | int [] dp = new int[n+1]; 15 | dp[0]=0; 16 | dp[1]=1; 17 | dp[2]=2; 18 | 19 | for(int i = 3; i stack=new Stack<>(); 26 | String result=""; 27 | for(int i=0;ileft == NULL && root->right == NULL) 30 | { 31 | return sum == root->val; 32 | } 33 | 34 | return hasPathSum(root->left, sum - root->val) 35 | || hasPathSum(root->right, sum - root->val); 36 | } 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /074. Search a 2D Matrix/Readme.txt: -------------------------------------------------------------------------------- 1 | Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: 2 | 3 | Integers in each row are sorted from left to right. 4 | The first integer of each row is greater than the last integer of the previous row. 5 | Example 1: 6 | 7 | Input: 8 | matrix = [ 9 | [1, 3, 5, 7], 10 | [10, 11, 16, 20], 11 | [23, 30, 34, 50] 12 | ] 13 | target = 3 14 | Output: true 15 | Example 2: 16 | 17 | Input: 18 | matrix = [ 19 | [1, 3, 5, 7], 20 | [10, 11, 16, 20], 21 | [23, 30, 34, 50] 22 | ] 23 | target = 13 24 | Output: false 25 | 74. 搜索二维矩阵 26 | 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性: 27 | 28 | 每行中的整数从左到右按升序排列。 29 | 每行的第一个整数大于前一行的最后一个整数。 30 | 示例 1: 31 | 32 | 输入: 33 | matrix = [ 34 | [1, 3, 5, 7], 35 | [10, 11, 16, 20], 36 | [23, 30, 34, 50] 37 | ] 38 | target = 3 39 | 输出: true 40 | 示例 2: 41 | 42 | 输入: 43 | matrix = [ 44 | [1, 3, 5, 7], 45 | [10, 11, 16, 20], 46 | [23, 30, 34, 50] 47 | ] 48 | target = 13 49 | 输出: false -------------------------------------------------------------------------------- /075.Sort Colors/075.Sort Colors.cpp: -------------------------------------------------------------------------------- 1 | 【最直观:平移插入】 2 | class Solution { 3 | public: 4 | void sortColors(int A[], int n) { 5 | int i = -1; 6 | int j = -1; 7 | int k = -1; 8 | for(int p = 0; p < n; p ++) 9 | { 10 | //根据第i个数字,挪动0~i-1串。 11 | if(A[p] == 0) 12 | { 13 | A[++k] = 2; //2往后挪 14 | A[++j] = 1; //1往后挪 15 | A[++i] = 0; //0往后挪 16 | } 17 | else if(A[p] == 1) 18 | { 19 | A[++k] = 2; 20 | A[++j] = 1; 21 | } 22 | else 23 | A[++k] = 2; 24 | } 25 | 26 | } 27 | }; -------------------------------------------------------------------------------- /075.Sort Colors/075.Sort Colors.java: -------------------------------------------------------------------------------- 1 | //如果只能扫一遍,很容易想到的就是左边存放0和1,右边存放2.两边往中间靠。 2 | 3 | //设置两个index,left记录第一个1的位置,left左边为0,right记录第一个非2的位置,right右边为2. 4 | 5 | //然后使用i从头到尾扫一遍,直到与right相遇。 6 | 7 | //i遇到0就换到左边去,遇到2就换到右边去,遇到1就跳过。 8 | 9 | //需要注意的是:由于left记录第一个1的位置,因此A[left]与A[i]交换后,A[left]为0,A[i]为1,因此i++; 10 | 11 | //而right记录第一个非2的位置,可能为0或1,因此A[right]与A[i]交换后,A[right]为2,A[i]为0或1,i不能前进,要后续判断。 12 | 13 | //由此该数组分为4段:[0,left)-->0; [left,i)-->1; [i,right]-->乱序; (right,n-1]-->2 14 | 15 | //0  0  0  1  1  1  2  1  0  2  1  2  2  2 16 | 17 | //           ^         ^             ^ 18 | 19 | //          left         i            right 20 | 21 | public void sortColors(int[] nums) { 22 | int j = 0, k = nums.length - 1; 23 | for (int i = 0; i <= k; i++) { 24 | // 遇到0和前面的交换 25 | if (nums[i] == 0) 26 | swap(nums, i, j++); 27 | // 遇到2和后面的交换 28 | else if (nums[i] == 2) 29 | swap(nums, i--, k--); 30 | } 31 | } 32 | 33 | private void swap(int[] nums, int i, int j) { 34 | int t = nums[i]; 35 | nums[i] = nums[j]; 36 | nums[j] = t; 37 | } 38 | -------------------------------------------------------------------------------- /075.Sort Colors/075.Sort Colors.js: -------------------------------------------------------------------------------- 1 | //---------------岁月------------------------- 2 | /** 3 | * @param {number[]} nums 4 | * @return {void} Do not return anything, modify nums in-place instead. 5 | */ 6 | var sortColors = function (nums) { 7 | let start = 0; 8 | let end = 0; 9 | let num1 = 0; 10 | let num2 = 0; 11 | for (let i = 0; i < nums.length; i++) { 12 | switch (nums[i]) { 13 | case 0: 14 | nums[start++] = 0; 15 | if (num1) { 16 | nums[end++] = 1; 17 | } else { 18 | end++; 19 | } 20 | if (num2) { 21 | nums[i] = 2; 22 | } 23 | break; 24 | case 1: 25 | num1++; 26 | nums[end++] = 1; 27 | if (num2) { 28 | nums[i] = 2; 29 | } 30 | break; 31 | case 2: 32 | num2++; 33 | break; 34 | } 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /075.Sort Colors/075.Sort Colors.py: -------------------------------------------------------------------------------- 1 | #--------------辰星------------------- 2 | class Solution: 3 | def sortColors(self, nums): 4 | """ 5 | :type nums: List[int] 6 | :rtype: void Do not return anything, modify nums in-place instead. 7 | """ 8 | if not nums: return None 9 | bucket = {} 10 | for item in nums: 11 | bucket[item] = bucket.get(item, 0) + 1 12 | pos = 0 13 | for item in sorted(bucket.keys()): 14 | limit = pos + bucket[item] 15 | nums[pos:limit] = [item] * bucket[item] 16 | pos = limit -------------------------------------------------------------------------------- /075.Sort Colors/Readme.md: -------------------------------------------------------------------------------- 1 | ![gongzhonghao](https://github.com/hanlaoshi/leetcode-One-topic-per-day/blob/master/img-storage/75.leetcode.png?raw=true) -------------------------------------------------------------------------------- /083. Remove Duplicates from Sorted List/083. Remove Duplicates from Sorted List.cpp: -------------------------------------------------------------------------------- 1 | //每个元素只保留一次,多个重复元素一次删除。 2 | 3 | /** 4 | * Definition for singly-linked list. 5 | * struct ListNode { 6 | * int val; 7 | * ListNode *next; 8 | * ListNode(int x) : val(x), next(NULL) {} 9 | * }; 10 | */ 11 | class Solution { 12 | public: 13 | ListNode *deleteDuplicates(ListNode *head) { 14 | if(head == NULL || head->next == NULL) 15 | { 16 | return head; 17 | } 18 | 19 | ListNode *pre = head; 20 | ListNode *cur = head->next; 21 | 22 | while(cur != NULL) 23 | { 24 | if(cur->val != pre->val) 25 | { 26 | pre = cur; 27 | cur = cur->next; 28 | continue; 29 | } 30 | 31 | while(cur->next != NULL && cur->next->val == pre->val) 32 | { 33 | cur = cur->next; 34 | } 35 | 36 | pre->next = cur->next; 37 | cur = pre->next; 38 | } 39 | 40 | return head; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /083. Remove Duplicates from Sorted List/083. Remove Duplicates from Sorted List.java: -------------------------------------------------------------------------------- 1 | /** 2 | 这道题是经典的双指针问题,用两个指针一前一后指向链表。如果两个指针指向的值相等,那么就让第二个指针一直往后挪,挪到与第一个指针不同为止。然后让第一个指针的next指向第二个指针,两个指针同时往后挪,进行下面的操作。 3 | 4 | 需要注意,当list的结尾几个node是重复的时候,例如1->2->3->3,那么ptr2会指向null,需要特殊处理,令ptr1.next = null,这样list尾部就不会丢。 5 | 6 | 其他情况就不用特殊处理结尾了,因为结尾没有重复值,只须遍历就够了,不用特殊处理尾部。 7 | */ 8 | public ListNode deleteDuplicates(ListNode head) { 9 | if(head == null || head.next == null) 10 | return head; 11 | 12 | ListNode ptr1 = head; 13 | ListNode ptr2 = head.next; 14 | 15 | while(ptr2!=null){ 16 | if(ptr1.val == ptr2.val){ 17 | ptr2 = ptr2.next; 18 | if(ptr2==null) 19 | ptr1.next = null; 20 | }else{ 21 | ptr1.next = ptr2; 22 | ptr1 = ptr1.next; 23 | ptr2 = ptr2.next; 24 | } 25 | } 26 | 27 | return head; 28 | } 29 | -------------------------------------------------------------------------------- /083. Remove Duplicates from Sorted List/readme.md: -------------------------------------------------------------------------------- 1 | Given a sorted linked list, delete all duplicates such that each element appear only once. 2 | 3 | Example 1: 4 | 5 | Input: 1->1->2 6 | Output: 1->2 7 | Example 2: 8 | 9 | Input: 1->1->2->3->3 10 | Output: 1->2->3 11 | 12 | 原题 13 | 删除一个有序链表中重复的元素,使得每个元素只出现一次。 14 | 注意点: 15 | 16 | 无 17 | 例子: 18 | 19 | 输入: 1->1->2->3->3 20 | 输出: 1->2->3 21 | -------------------------------------------------------------------------------- /084.Largest Rectangle in Histogram/Largest Rectangle in Histogram.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def largestRectangleArea(self, heights): 3 | """ 4 | :type heights: List[int] 5 | :rtype: int 6 | """ 7 | stack = list() 8 | res = 0 9 | heights.append(0) 10 | N = len(heights) 11 | for i in range(N): 12 | if not stack or heights[i] > heights[stack[-1]]: 13 | stack.append(i) 14 | else: 15 | while stack and heights[i] <= heights[stack[-1]]: 16 | h = heights[stack[-1]] 17 | stack.pop() 18 | w = i if not stack else i - stack[-1] - 1 19 | res = max(res, h * w) 20 | stack.append(i) 21 | return res 22 | -------------------------------------------------------------------------------- /088. Merge Sorted Array/088. Merge Sorted Array.cpp: -------------------------------------------------------------------------------- 1 | //把数组依次从后往前放可以减少大量的数据移动。 2 | 3 | class Solution { 4 | public: 5 | void merge(vector& nums1, int m, vector& nums2, int n) { 6 | nums1.resize(m+n); 7 | int p1 = m-1; 8 | int p2 = n-1; 9 | int tmp = m+n-1; 10 | while(p1+1&&p2+1){ 11 | if(nums1[p1]>nums2[p2]){ 12 | nums1[tmp--] = nums1[p1--]; 13 | }else{ 14 | nums1[tmp--] = nums2[p2--]; 15 | } 16 | } 17 | if(p2+1) 18 | while(p2+1){ 19 | nums1[p2] = nums2[p2]; 20 | p2--; 21 | } 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /088. Merge Sorted Array/088. Merge Sorted Array.java: -------------------------------------------------------------------------------- 1 | //从后向前考虑。如果A中的先遍历完,应把B中剩下的元素复制到A中。 2 | 3 | public void merge(int[] nums1, int m, int[] nums2, int n) { 4 | int index = m + n - 1; 5 | int i = m - 1; 6 | int j = n - 1; 7 | while (i >= 0 && j >= 0) 8 | if (nums1[i] >= nums2[j]) { 9 | nums1[index] = nums1[i]; 10 | i--; 11 | index--; 12 | } else { 13 | nums1[index] = nums2[j]; 14 | j--; 15 | index--; 16 | } 17 | //继续遍历剩下的元素 18 | if (i == -1) { 19 | while (j >= 0) { 20 | nums1[index] = nums2[j]; 21 | j--; 22 | index--; 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /088. Merge Sorted Array/readme.md: -------------------------------------------------------------------------------- 1 | Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. 2 | 3 | Note: 4 | 5 | The number of elements initialized in nums1 and nums2 are m and n respectively. 6 | You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. 7 | Example: 8 | 9 | Input: 10 | nums1 = [1,2,3,0,0,0], m = 3 11 | nums2 = [2,5,6], n = 3 12 | 13 | Output: [1,2,2,3,5,6] 14 | 15 | 将两个有序数组合并成为一个。 16 | 注意点: 17 | 18 | 第一个数组有充足的空间来存放第二个数组中的元素 19 | 第一个数组的有效长度为m,第二个的有效长度为n 20 | 在原数组上修改,没有返回值 21 | 例子: 22 | 23 | 输入: nums1 = [1, 1, 2, 2, 4, 0, 0, 0, 0], m = 5, nums2 = [0, 0, 2, 3], n = 4 24 | 输出: 无(nums1变为[0, 0, 1, 1, 2, 2, 2, 3, 4]) 25 | -------------------------------------------------------------------------------- /089.Gray Code/089.Gray Code.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | public: 4 | vector grayCode(int n) { 5 | if (n == 0) return {0}; 6 | if (n == 1) return {0, 1}; 7 | vector res; 8 | vector pre = grayCode(n - 1); 9 | for (int p : pre) { 10 | res.push_back(p); 11 | } 12 | for (auto p = pre.rbegin(); p < pre.rend(); p++) { 13 | res.push_back((1 << (n - 1)) + *p); 14 | } 15 | return res; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /089.Gray Code/089.Gray Code.java: -------------------------------------------------------------------------------- 1 | /** 2 | 递归生成码表 3 | 这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造: 4 | 1位格雷码有两个码字 5 | (n+1)位格雷码中的前2n个码字等于n位格雷码的码字,按顺序书写,加前缀0 6 | (n+1)位格雷码中的后2n个码字等于n位格雷码的码字,按逆序书写,加前缀1 7 | 8 | */ 9 | public class Solution { 10 | 11 | public List grayCode(int n) { 12 | List result = new LinkedList<>(); 13 | if (n >= 0) { 14 | // 格雷码的前半部分 15 | result.add(0); 16 | // 格雷码最高位的值(非0时) 17 | int t = 1; 18 | // 每一次外循环求出的是位数i+1位的格雷码表,其相当于长度为i+1位的格雷码表的前半部分 19 | for (int i = 0; i < n; i++) { 20 | // 求出的长度为i+1位格雷码表的后半部分,前半部分由长度为i位的格雷码表给出 21 | for (int j = result.size() - 1; j >= 0; j--) { 22 | result.add(result.get(j) ^ t); 23 | } 24 | // 最高位右移 25 | t <<= 1; 26 | } 27 | } 28 | return result; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /090. Subsets II/090. Subsets II.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 在 Subsets 迭代版本的基础上思考。在迭代重复元素的时候会生成重复的结果,那么在迭代重复元素时要特殊处理一下。 3 | 就拿[1,2,2]来说,在迭代完1之后结果集为[[], [1]],迭代第一个2后,[[], [1], [2], [1,2]],接下来就要迭代重复的元素2了, 4 | 此时如果遍历在迭代第一个2之前就存在的结果集元素([[], [1]])时,就会产生重复, 5 | 我们只能在上一轮迭代产生的新的结果中继续添加。 6 | 所以要一个额外的变量来表示在结果集中的哪个位置开始遍历。 7 | ''' 8 | class Solution(object): 9 | def subsetsWithDup(self, nums): 10 | """ 11 | :type nums: List[int] 12 | :rtype: List[List[int]] 13 | """ 14 | result = [[]] 15 | nums.sort() 16 | temp_size = 0 17 | for i in range(len(nums)): 18 | start = temp_size if i >= 1 and nums[i] == nums[i - 1] else 0 19 | temp_size = len(result) 20 | for j in range(start, temp_size): 21 | result.append(result[j] + [nums[i]]) 22 | return result 23 | -------------------------------------------------------------------------------- /090. Subsets II/readme.md: -------------------------------------------------------------------------------- 1 | Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set). 2 | 3 | Note: The solution set must not contain duplicate subsets. 4 | 5 | Example: 6 | 7 | Input: [1,2,2] 8 | 9 | Output: 10 | [ 11 | 12 | [2], 13 | 14 | [1], 15 | 16 | [1,2,2], 17 | 18 | [2,2], 19 | 20 | [1,2], 21 | 22 | [] 23 | 24 | ] 25 | 26 | 罗列出一个包含重复数字的集合的所有的子集。 27 | 28 | 注意点: 29 | 30 | 子集中的元素需要按照不降序排列 31 | 32 | 结果集中不能重复 33 | 34 | 例子: 35 | 36 | 输入: nums = [1,2,2] 37 | 38 | 输出: 39 | 40 | [ 41 | [2], 42 | 43 | [1], 44 | 45 | [1,2,2], 46 | 47 | [2,2], 48 | 49 | [1,2], 50 | 51 | [] 52 | 53 | ] 54 | -------------------------------------------------------------------------------- /092. Reverse Linked List II/092. Reverse Linked List II.cpp: -------------------------------------------------------------------------------- 1 | //主要思路是记录下翻转的链表的头和尾,分别赋值。 2 | //方法来源:https://blog.csdn.net/a2331046/article/details/51326259 3 | 4 | 5 | ListNode* reverseBetween(ListNode* head, int m, int n) { 6 | ListNode* pre = NULL; 7 | ListNode* cur = head; 8 | ListNode* tmpTail; 9 | for (int i = 1 ; i < m;i++){ 10 | pre = cur; 11 | cur = cur->next; 12 | } 13 | tmpTail = cur; 14 | for (int i = m ; i <= n ; i++){ 15 | ListNode* next = cur->next; 16 | cur->next = pre; 17 | pre = cur; 18 | cur = next; 19 | } 20 | if (m==1) head = pre; 21 | else tmpTail->next->next = pre; 22 | 23 | tmpTail->next = cur; 24 | return head; 25 | } 26 | -------------------------------------------------------------------------------- /092. Reverse Linked List II/092. Reverse Linked List II.py: -------------------------------------------------------------------------------- 1 | #进行一遍遍历,把第m到n个元素进行翻转,即依次插入到第m个节点的头部。 2 | #方法来源:https://blog.csdn.net/fuxuemingzhu/article/details/80794665 3 | class Solution(object): 4 | def reverseBetween(self, head, m, n): 5 | """ 6 | :type head: ListNode 7 | :type m: int 8 | :type n: int 9 | :rtype: ListNode 10 | """ 11 | count = 1 12 | root = ListNode(0) 13 | root.next = head 14 | pre = root 15 | while pre.next and count < m: 16 | pre = pre.next 17 | count += 1 18 | if count < m: 19 | return head 20 | mNode = pre.next 21 | curr = mNode.next 22 | while curr and count < n: 23 | next = curr.next 24 | curr.next = pre.next 25 | pre.next = curr 26 | mNode.next = next 27 | curr = next 28 | count += 1 29 | return root.next 30 | -------------------------------------------------------------------------------- /092. Reverse Linked List II/readme.md: -------------------------------------------------------------------------------- 1 | Reverse a linked list from position m to n. Do it in one-pass. 2 | 3 | Note: 1 ≤ m ≤ n ≤ length of list. 4 | 5 | Example: 6 | 7 | Input: 1->2->3->4->5->NULL, m = 2, n = 4 8 | 9 | Output: 1->4->3->2->5->NULL 10 | 11 | 在只遍历一遍且不申请额外空间的情况下将一个链表的第m到n个元素进行翻转。 12 | 13 | 注意点: 14 | 15 | m和n满足如下条件:1 ≤ m ≤ n ≤链表长度 16 | 17 | 例子: 18 | 19 | 输入: 1->2->3->4->5->NULL, m = 2, n = 4 20 | 21 | 输出: 1->4->3->2->5->NULL 22 | -------------------------------------------------------------------------------- /094.Binary Tree Inorder Traversal/Binary Tree Inorder Traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector twoSum(vector& nums, int target) { 4 | unordered_map m; 5 | vector res; 6 | for (int i = 0; i < nums.size(); ++i) { 7 | m[nums[i]] = i; 8 | } 9 | for (int i = 0; i < nums.size(); ++i) { 10 | int t = target - nums[i]; 11 | if (m.count(t) && m[t] != i) { 12 | res.push_back(i); 13 | res.push_back(m[t]); 14 | break; 15 | } 16 | } 17 | return res; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /094.Binary Tree Inorder Traversal/Binary Tree Inorder Traversal.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List inorderTraversal(TreeNode root) { 3 | Stack stack = new Stack<>(); 4 | List list = new ArrayList<>(); 5 | while(true){ 6 | if (root != null){ 7 | stack.push(root); 8 | root = root.left; 9 | } else { 10 | if (stack.empty()) { 11 | return list; 12 | } 13 | root = stack.pop(); 14 | list.add(root.val); 15 | root = root.right; 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /095. Unique Binary Search Trees II—Dynamic Programming/Readme.md: -------------------------------------------------------------------------------- 1 | 95.Unique Binary Search Trees II 2 | 3 | Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ... n. 4 | 5 | Example: 6 | 7 | Input: 3 8 | Output: 9 | [ 10 | [1,null,3,2], 11 | [3,2,null,1], 12 | [3,1,null,null,2], 13 | [2,1,3], 14 | [1,null,2,null,3] 15 | ] 16 | Explanation: 17 | The above output corresponds to the 5 unique BST's shown below: 18 | 19 | 1 3 3 2 1 20 | \ / / / \ \ 21 | 3 2 1 1 3 2 22 | / / \ \ 23 | 2 1 2 3 -------------------------------------------------------------------------------- /095. Unique Binary Search Trees II—Dynamic Programming/Unique Binary Search Trees II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | 4 | vector generateTrees(int n) { 5 | vector t; 6 | if(n==0) 7 | { 8 | return t; 9 | } 10 | 11 | return f(1,n); 12 | }; 13 | 14 | vector f(int l,int r)//递归建立左右子树 15 | { 16 | vector ans; 17 | 18 | if(l>r) 19 | { 20 | ans.push_back(NULL); 21 | } 22 | 23 | for(int k=l;k<=r;k++)//k为当前对应情况的根节点 24 | { 25 | vector left=f(l,k-1); 26 | vector right=f(k+1,r); 27 | 28 | for(int i=0;ileft=left[i]; 34 | temp->right=right[j]; 35 | ans.push_back(temp); 36 | } 37 | } 38 | } 39 | 40 | return ans; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /096. Unique Binary Search Trees—tree/Readme.md: -------------------------------------------------------------------------------- 1 | 096. 不同的二叉搜索树 2 | 3 | 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 4 | 5 | 示例: 6 | 7 | 输入: 3 8 | 输出: 5 9 | 解释: 10 | 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 11 | 12 | 1 3 3 2 1 13 | \ / / / \ \ 14 | 3 2 1 1 3 2 15 | / / \ \ 16 | 2 1 2 3 17 | 18 | 096. Unique Binary Search Trees 19 | Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? 20 | 21 | Example: 22 | 23 | Input: 3 24 | Output: 5 25 | Explanation: 26 | Given n = 3, there are a total of 5 unique BST's: 27 | 28 | 1 3 3 2 1 29 | \ / / / \ \ 30 | 3 2 1 1 3 2 31 | / / \ \ 32 | 2 1 2 3 -------------------------------------------------------------------------------- /096. Unique Binary Search Trees—tree/Unique Binary Search Trees.cpp: -------------------------------------------------------------------------------- 1 | 题目翻译: 2 | 3 | 给定n,有多少种结构独特的值为1...n的BST(二叉查找树)? 4 | 例如, 5 | 给定n = 3,共有5种独特的BST。 6 | 7 | 分析: 8 |         自底向上。对于i个节点的情况,将第j个节点作为根节点,则左子树有j-1个节点,右子树有i-j个节点,左右子树不同BST种数相乘即得到j为根节点时的总数,对j从1到i求和,即得到i个节点不同BST的总数。 9 | 10 |         另外这是一种Catalan数,公式为。 ![Tree](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/96.tree.png) 11 | 12 | class Solution { 13 | public: 14 | int numTrees(int n) { 15 | vector num(n + 1, 0); 16 | num[0] = 1; 17 | num[1] = 1; 18 | 19 | for(int i = 2; i <= n; i++) 20 | for(int j = 1; j <= i; j++) 21 | { 22 | num[i] += num[j - 1] * num[i - j]; 23 | } 24 | 25 | return num[n]; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /096. Unique Binary Search Trees—tree/Unique Binary Search Trees.java: -------------------------------------------------------------------------------- 1 | 题目翻译: 2 | 3 | 给定n,有多少种结构独特的值为1...n的BST(二叉查找树)? 4 | 例如, 5 | 给定n = 3,共有5种独特的BST。 6 | 7 | 分析: 8 |         自底向上。对于i个节点的情况,将第j个节点作为根节点,则左子树有j-1个节点,右子树有i-j个节点,左右子树不同BST种数相乘即得到j为根节点时的总数,对j从1到i求和,即得到i个节点不同BST的总数。 9 | 10 |         另外这是一种Catalan数,公式为。 ![Tree](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/96.tree.png) 11 | 12 | 13 | 14 | public class Solution { 15 | public int numTrees(int n) { 16 | if(n == 0 || n == 1) { 17 | return 1; 18 | } 19 | int[] nums = new int[n+1]; 20 | 21 | nums[0] = 1; 22 | nums[1] = 1; 23 | 24 | for(int i = 2;i <= n;i++) { 25 | for(int j = 0;j < i;j++) { 26 | nums[i] += nums[j]*nums[i-j-1]; 27 | } 28 | } 29 | 30 | return nums[n]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /096. Unique Binary Search Trees—tree/Unique Binary Search Trees.py: -------------------------------------------------------------------------------- 1 | 题目翻译: 2 | 给定n,有多少种结构独特的值为1...n的BST(二叉查找树)? 3 | 例如, 4 | 给定n = 3,共有5种独特的BST。 5 | 分析: 6 |      自底向上。对于i个节点的情况,将第j个节点作为根节点,则左子树有j-1个节点,右子树有i-j个节点, 7 | 左右子树不同BST种数相乘即得到j为根节点时的总数,对j从1到i求和,即得到i个节点不同BST的总数。 8 | 二方法根据Catalan方法计算。(未完成) 9 | #---------辰星出品---------- 10 | class Solution(object): 11 | def numTrees(self, n): 12 | """ 13 | :type n: int 14 | :rtype: int 15 | """ 16 | dp = [1] 17 | for i in range(1, n+1): 18 | total = 0 19 | for j in range(1, i+1): 20 | total += dp[j - 1] * dp[i - j] 21 | dp.append(total) 22 | return dp[n] 23 | #--------------第二种-------------- 24 | class Solution: 25 | # @return an integer 26 | def numTrees(self, n): 27 | num = [0 for i in range(n + 1)] 28 | num[0] = 1 29 | num[1] = 1 30 | 31 | for i in range(2, n + 1): 32 | for j in range(1, i + 1): 33 | num[i] += num[j - 1] * num[i - j] 34 | 35 | return num[n] 36 | -------------------------------------------------------------------------------- /100. Same Tree/Readme.txt: -------------------------------------------------------------------------------- 1 | Given two binary trees, write a function to check if they are the same or not. 2 | 3 | Two binary trees are considered the same if they are structurally identical and the nodes have the same value. 4 | 5 | `Example 1:` 6 | 7 | Input: 1 1 8 | / \ / \ 9 | 2 3 2 3 10 | 11 | [1,2,3], [1,2,3] 12 | 13 | `Output: true` 14 | 15 | `Example 2:` 16 | 17 | Input: 1 1 18 | / \ 19 | 2 2 20 | 21 | [1,2], [1,null,2] 22 | 23 | `Output: false` 24 | 25 | `Example 3:` 26 | 27 | Input: 1 1 28 | / \ / \ 29 | 2 1 1 2 30 | 31 | [1,2,1], [1,1,2] 32 | 33 | `Output: false` 34 | 35 | `原题` 36 | 37 | 判断两棵二叉树是否相等。两棵二叉树仅在它们的形状相同且每个节点的值相等时才判为相等。 38 | 39 | `注意点:` 40 | 41 | 无 42 | 43 | `例子:` 44 | 45 | `输入:` 46 | 47 | 2 2 48 | p = / \ q = / \ 49 | 1 3 1 3 50 | 51 | `输出: True` 52 | -------------------------------------------------------------------------------- /101. Symmetric Tree—Breadth-first Search/101. Symmetric Tree—Breadth-first Search.java: -------------------------------------------------------------------------------- 1 | //1. 树是空的,true。 2 | 3 | //2. 判断这棵树的左子树和右子树是否对称。 4 | 5 | //3. 两棵子树的对称条件:根节点相等,左子树的左子树和右子树的右子树对称,左子树的右子树和右子树的左子树对称: 6 | 7 |   8 | 9 | //       2            2 10 | //      / \          / \ 11 | //     3   4        4   3 12 | //    / \ / \      / \ / \ 13 | //   5  6 7  8    8  7 6  5 14 | /** 15 | * Definition for a binary tree node. 16 | * public class TreeNode { 17 | * int val; 18 | * TreeNode left; 19 | * TreeNode right; 20 | * TreeNode(int x) { val = x; } 21 | * } 22 | */ 23 | class Solution { 24 | public boolean isSymmetric(TreeNode root) { 25 | if (root == null) { 26 | return true; 27 | } 28 | else { 29 | return isSymmetric(root.left, root.right); 30 | } 31 | } 32 | private boolean isSymmetric(TreeNode left, TreeNode right) { 33 | if (left == null && right == null) { 34 | return true; 35 | } 36 | else if (left == null || right == null) { 37 | return false; 38 | } 39 | return left.val == right.val && isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /101. Symmetric Tree—Breadth-first Search/Readme.txt: -------------------------------------------------------------------------------- 1 | 101. Symmetric Tree 2 | Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). 3 | 4 | For example, this binary tree [1,2,2,3,4,4,3] is symmetric: 5 | 6 | 1 7 | / \ 8 | 2 2 9 | / \ / \ 10 | 3 4 4 3 11 | But the following [1,2,2,null,3,null,3] is not: 12 | 1 13 | / \ 14 | 2 2 15 | \ \ 16 | 3 3 17 | Note: 18 | Bonus points if you could solve it both recursively and iteratively. -------------------------------------------------------------------------------- /102. Binary Tree Level Order Traversal—Breadth-first Search/102. Binary Tree Level Order Traversal—Breadth-first Search.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> levelOrder(TreeNode* root) { 4 | vector> result; 5 | 6 | if (root == nullptr) { 7 | return result; 8 | } 9 | 10 | std::list temp; 11 | temp.push_back(root); 12 | 13 | while (temp.size() != 0) { 14 | vector level; 15 | int size = temp.size(); 16 | for(int i = 0; i < size; i++) { 17 | TreeNode *node = temp.front(); 18 | level.push_back(node->val); 19 | 20 | if (node->left) temp.push_back(node->left); 21 | if (node->right) temp.push_back(node->right); 22 | 23 | temp.pop_front(); 24 | } 25 | 26 | result.push_back(level); 27 | } 28 | 29 | return result; 30 | } 31 | }; -------------------------------------------------------------------------------- /102. Binary Tree Level Order Traversal—Breadth-first Search/102. Binary Tree Level Order Traversal—Breadth-first Search.java: -------------------------------------------------------------------------------- 1 | 2 | //与树的前中后序遍历的DFS思想不同,层次遍历用到的是BFS思想。一般DFS用递归去实现(也可以用栈实现),BFS需要用队列去实现。 3 | 4 | //层次遍历的步骤是: 5 | 6 | //1.对于不为空的结点,先把该结点加入到队列中 7 | 8 | //2.从队中拿出结点,如果该结点的左右结点不为空,就分别把左右结点加入到队列中 9 | 10 | //3.重复以上操作直到队列为空 11 | 12 | public class Solution{ 13 | class TreeNode { 14 | int val; 15 | TreeNode left; 16 | TreeNode right; 17 | TreeNode(int x) { val = x; } 18 | } 19 | public static void LaywerTraversal(TreeNode root){ 20 | if(root==null) return; 21 | LinkedList list = new LinkedList(); 22 | list.add(root); 23 | TreeNode currentNode; 24 | while(!list.isEmpty()){ 25 | currentNode=list.poll(); 26 | System.out.println(currentNode.val); 27 | if(currentNode.left!=null){ 28 | list.add(currentNode.left); 29 | } 30 | if(currentNode.right!=null){ 31 | list.add(currentNode.right); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /102. Binary Tree Level Order Traversal—Breadth-first Search/102. Binary Tree Level Order Traversal—Breadth-first Search.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def levelOrder(self, root): 3 | """ 4 | :type root: TreeNode 5 | :rtype: List[List[int]] 6 | """ 7 | if not root: 8 | return [] 9 | result=[] 10 | stackNode=[root] 11 | while stackNode: 12 | currentNode,temp=[],[] 13 | for i in stackNode: 14 | temp.append(i.val) 15 | 16 | if i.left: 17 | currentNode.append(i.left) 18 | if i.right: 19 | currentNode.append(i.right) 20 | stackNode=currentNode 21 | result.append(temp) 22 | return result -------------------------------------------------------------------------------- /102. Binary Tree Level Order Traversal—Breadth-first Search/Readme.txt: -------------------------------------------------------------------------------- 1 | Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). 2 | 3 | For example: 4 | Given binary tree [3,9,20,null,null,15,7], 5 | 3 6 | / \ 7 | 9 20 8 | / \ 9 | 15 7 10 | return its level order traversal as: 11 | [ 12 | [3], 13 | [9,20], 14 | [15,7] 15 | ] -------------------------------------------------------------------------------- /103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search/103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> zigzagLevelOrder(TreeNode* root) { 4 | vector>ans; 5 | if(root==NULL)return ans; 6 | queueq; 7 | q.push(root); 8 | int flag=1; 9 | while(!q.empty()){ 10 | queueqt; 11 | vectorres; 12 | while(!q.empty()){ 13 | TreeNode *t=q.front();q.pop(); 14 | res.push_back(t->val); 15 | if(t->left)qt.push(t->left); 16 | if(t->right)qt.push(t->right); 17 | } 18 | if(flag<0)reverse(res.begin(),res.end()); 19 | flag=-flag;//标志是否需要反转 20 | ans.push_back(res); 21 | q=qt; 22 | } 23 | return ans; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search/103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode(int x) { val = x; } 8 | * } 9 | */ 10 | class Solution { 11 | public List> zigzagLevelOrder(TreeNode root) { 12 | List> result = new ArrayList<>(); 13 | travel(root,result,0); 14 | return result; 15 | } 16 | public void travel(TreeNode root, List> result, int level){ 17 | if(root == null){ 18 | return; 19 | } 20 | if(result.size() <= level){ 21 | List newLevel = new LinkedList<>(); 22 | result.add(newLevel); 23 | } 24 | List collection = result.get(level); 25 | if(level % 2 == 0) collection.add(root.val); 26 | else collection.add(0, root.val); 27 | travel(root.left, result, level+1); 28 | travel(root.right, result, level+1); 29 | 30 | 31 | } 32 | } -------------------------------------------------------------------------------- /103. Binary Tree Zigzag Level Order Traversal—Breadth-first Search/Readme.txt: -------------------------------------------------------------------------------- 1 | Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). 2 | 3 | For example: 4 | Given binary tree [3,9,20,null,null,15,7], 5 | 3 6 | / \ 7 | 9 20 8 | / \ 9 | 15 7 10 | return its zigzag level order traversal as: 11 | [ 12 | [3], 13 | [20,9], 14 | [15,7] 15 | ] -------------------------------------------------------------------------------- /104. Maximum Depth of Binary Tree/104. Maximum Depth of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 多年未见大佬出品 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | int work(TreeNode* root, int cc) { 15 | if (root == NULL) return cc; 16 | return max(work(root->left, cc + 1), work(root->right, cc + 1)); 17 | } 18 | public: 19 | int maxDepth(TreeNode* root) { 20 | return work(root, 0); 21 | } 22 | }; 23 | 24 | 25 | // 李承民大佬出品 26 | 27 | /** 28 | * Definition for a binary tree node. 29 | * type TreeNode struct { 30 | * Val int 31 | * Left *TreeNode 32 | * Right *TreeNode 33 | * } 34 | */ 35 | func max(a, b int) int { 36 | if (a > b) { 37 | return a 38 | } 39 | return b 40 | } 41 | 42 | func maxDepth(root *TreeNode) int { 43 | if nil == root { 44 | return 0 45 | } 46 | 47 | return max(maxDepth(root.Left), maxDepth(root.Right))+1 48 | } 49 | -------------------------------------------------------------------------------- /104. Maximum Depth of Binary Tree/104. Maximum Depth of Binary Tree.java: -------------------------------------------------------------------------------- 1 | // 多年未见大佬出品 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * public class TreeNode { 6 | * int val; 7 | * TreeNode left; 8 | * TreeNode right; 9 | * TreeNode(int x) { val = x; } 10 | * } 11 | */ 12 | class Solution { 13 | int work(TreeNode root, int cc) { 14 | if (root == null) return cc; 15 | int tmp1 = work(root.left, cc + 1); 16 | int tmp2 = work(root.right, cc + 1); 17 | return tmp1 > tmp2 ? tmp1 : tmp2; 18 | } 19 | public int maxDepth(TreeNode root) { 20 | return work(root, 0); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /104. Maximum Depth of Binary Tree/Readme.txt: -------------------------------------------------------------------------------- 1 | Given a binary tree, find its maximum depth. 2 | 3 | The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 4 | 5 | Note: A leaf is a node with no children. 6 | 7 | Example: 8 | 9 | Given binary tree [3,9,20,null,null,15,7], 10 | 11 | 3 12 | / \ 13 | 9 20 14 | / \ 15 | 15 7 16 | return its depth = 3. 17 | 18 | 求一颗二叉树的最大深度,最大深度指跟节点到最底层叶子节点的距离。 19 | 注意点: 20 | 21 | 无 22 | 例子: 23 | 24 | 输入: 25 | 26 | 3 27 | / \ 28 | 9 20 29 | / \ 30 | 15 7 31 | / 32 | 14 33 | 输出: 4 34 | -------------------------------------------------------------------------------- /105. Construct Binary Tree from Preorder and Inorder Traversal/105. Construct Binary Tree from Preorder and Inorder Traversal.cpp: -------------------------------------------------------------------------------- 1 | //通过二叉树的前序遍历和中序遍历来构建二叉树,通过递归可以很容易的解决这个问题,在遇到二叉树的问题,应该习惯先画图再来解决 2 | //原文:https://blog.csdn.net/u014265347/article/details/76400062 3 | 4 | class Solution { 5 | public: 6 | TreeNode* buildTree(vector& preorder, vector& inorder) { 7 | int l1 = 0; 8 | int l2 = 0; 9 | int r1 = preorder.size() - 1; 10 | int r2 = inorder.size() - 1; 11 | TreeNode *s = (TreeNode*)malloc(sizeof(TreeNode)); 12 | //s = NULL; 13 | s = CreateBT(preorder, inorder, l1, r1, l2, r2); 14 | return s; 15 | } 16 | 17 | TreeNode* CreateBT(vector& preorder, vector& inorder, int l1, int r1, int l2, int r2) 18 | { 19 | TreeNode* s; 20 | int i; 21 | if (l1 > r1) 22 | return NULL; 23 | s = (TreeNode*)malloc(sizeof(TreeNode)); 24 | s->left = s->right = NULL; 25 | for (i = l2; i <= r2; i++) 26 | { 27 | if (inorder[i] == preorder[l1]) 28 | { 29 | break; 30 | } 31 | } 32 | s->val = inorder[i]; 33 | s->left = CreateBT(preorder, inorder, l1 + 1, l1 + i - l2, l2, i - 1); 34 | s->right = CreateBT(preorder, inorder, l1 + i - l2 + 1, r1, i + 1, r2); 35 | return s; 36 | } 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /105. Construct Binary Tree from Preorder and Inorder Traversal/105. Construct Binary Tree from Preorder and Inorder Traversal.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 因为先序中的节点为根节点,所以取出先序的第一个节点 3 | 用先序的第一个节点可以将中序分成左右子树,然后取出先序的第二个节点将左右子树再次划分 4 | 当将中序全部划分为单个点时就结束 5 | 开始递归的时候用了列表作为参数,结果内存溢出,改用下标作参数,先序和中序序列作为全局变量。 6 | 7 | ''' 8 | 9 | class TreeNode(object): 10 | def __init__(self, x): 11 | self.val = x 12 | self.left = None 13 | self.right = None 14 | 15 | 16 | class Solution(object): 17 | def buildTree(self, preorder, inorder): 18 | """ 19 | :type preorder: List[int] 20 | :type inorder: List[int] 21 | :rtype: TreeNode 22 | """ 23 | self.preorder = preorder 24 | self.inorder = inorder 25 | return self._buildTree(0, len(preorder), 0, len(inorder)) 26 | 27 | def _buildTree(self, pre_start, pre_end, in_start, in_end): 28 | if pre_start >= pre_end: 29 | return None 30 | root = TreeNode(self.preorder[pre_start]) 31 | offset = self.inorder[in_start:in_end + 1].index(root.val) 32 | root.left = self._buildTree(pre_start + 1, pre_start + offset + 1, in_start, in_start + offset) 33 | root.right = self._buildTree(pre_start + offset + 1, pre_end, in_start + offset + 1, in_end) 34 | return root 35 | -------------------------------------------------------------------------------- /105. Construct Binary Tree from Preorder and Inorder Traversal/readme.md: -------------------------------------------------------------------------------- 1 | Given preorder and inorder traversal of a tree, construct the binary tree. 2 | 3 | Note: 4 | You may assume that duplicates do not exist in the tree. 5 | 6 | For example, given 7 | 8 | preorder = [3,9,20,15,7] 9 | inorder = [9,3,15,20,7] 10 | Return the following binary tree: 11 | 12 | 3 13 | / \ 14 | 9 20 15 | / \ 16 | 15 7 17 | 18 | 19 | 通过一棵二叉树的前序和中序排列来得出它的树形结构。 20 | 注意点: 21 | 22 | 无 23 | 24 | 例子: 25 | 26 | 输入: preorder = [3,9,20,15,14,7], inorder = [9,3,14,15,20,7] 27 | 输出: 28 | 29 | 3 30 | / \ 31 | 9 20 32 | / \ 33 | 15 7 34 | / 35 | 14 36 | 37 | -------------------------------------------------------------------------------- /107. Binary Tree Level Order Traversal II—Breadth-first Search/107. Binary Tree Level Order Traversal II—Breadth-first Search.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> levelOrderBottom(TreeNode* root) { 4 | vector>v; 5 | stack>s; 6 | queueq; 7 | q.push(root); //根节点入队 8 | if(root == NULL) 9 | return v ; 10 | while(!q.empty()){ //队列不空 11 | vectorvv; 12 | queue next ; // 建立第二个队列 用来存放下一层的结点 13 | 14 | while(!q.empty()){ //遍历每层的结点 这层循环是核心 其他都是为了满足OJ输出 15 | 16 | TreeNode* tre = q.front() ; 17 | vv.push_back(tre->val); //访问该结点,为了满足输出要求,所以有点复杂, 18 | q.pop(); //对头元素出队 19 | if(tre->left!=NULL){ //它有左子树 20 | next.push(tre->left); 21 | } 22 | if(tre->right!=NULL){ //它有右子树 23 | next.push(tre->right); 24 | } 25 | 26 | } 27 | s.push(vv); //将每层结点入栈 28 | //v.push_back(vv); 29 | q=next; // // 遍历完后进入下一层 30 | } 31 | while(!s.empty()){ //将每层结点倒序输出 32 | v.push_back(s.top()); 33 | s.pop(); 34 | } 35 | return v; 36 | } 37 | }; -------------------------------------------------------------------------------- /107. Binary Tree Level Order Traversal II—Breadth-first Search/107. Binary Tree Level Order Traversal II—Breadth-first Search.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List> traverse(TreeNode root, int level, List> res) { 3 | if (res.size() <= level && (root.left != null || root.right != null)) 4 | res.add(0, new LinkedList<>()); 5 | if (root.left != null) { 6 | res.get(res.size() - level - 1).add(root.left.val); 7 | traverse(root.left, level + 1, res); 8 | } 9 | if (root.right != null) { 10 | res.get(res.size() - level - 1).add(root.right.val); 11 | traverse(root.right, level + 1, res); 12 | } 13 | return res; 14 | } 15 | 16 | public List> levelOrderBottom(TreeNode root) { 17 | List> res = new LinkedList<>(); 18 | if (root == null) return res; 19 | List item = new LinkedList<>(); 20 | item.add(root.val); 21 | res.add(item); 22 | res = traverse(root, 1, res); 23 | return res; 24 | } 25 | } -------------------------------------------------------------------------------- /107. Binary Tree Level Order Traversal II—Breadth-first Search/107. Binary Tree Level Order Traversal II—Breadth-first Search.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def levelOrderBottom(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: List[List[int]] 13 | """ 14 | #bfs广度优先搜索,不熟悉可以网上参考bfs代码 15 | if not root: 16 | return []#为空则返回空列表 17 | queue=[root]#使用列表实现队列的功能,首先存储root 18 | res=[] 19 | while queue:#当queue不为空时 20 | nodes=[]#存节点,每次循环前置空,每次只装一部分 21 | node_values=[]#存节点的值 22 | for node in queue: 23 | if node.left: 24 | nodes.append(node.left)#将左子树装入队列中 25 | if node.right: 26 | nodes.append(node.right) 27 | node_values+=[node.val]#因为每次循环node_values都会置空,所以最终结果保存在res里,node_values只是一小部分结果 28 | res=[node_values]+res#实现从底到顶,node_values放前面. 29 | queue=nodes#将新添加的节点重新赋值给queue 30 | return res 31 | -------------------------------------------------------------------------------- /107. Binary Tree Level Order Traversal II—Breadth-first Search/Readme.txt: -------------------------------------------------------------------------------- 1 | Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). 2 | 3 | For example: 4 | Given binary tree [3,9,20,null,null,15,7], 5 | 3 6 | / \ 7 | 9 20 8 | / \ 9 | 15 7 10 | return its bottom-up level order traversal as: 11 | [ 12 | [15,7], 13 | [9,20], 14 | [3] 15 | ] -------------------------------------------------------------------------------- /108. Convert Sorted Array to Binary Search Tree/108. Convert Sorted Array to Binary Search Tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 目的是要得到一个平衡二叉树,也就说是每棵数的根节点应该是整棵树上结点的中位数。 3 | 所以取数组的中位数作为根节点,中位数左边为左子树的数组,右边为右子数的数组。以此类推。 4 | */ 5 | 6 | /** 7 | * Definition for a binary tree node. 8 | * struct TreeNode { 9 | * int val; 10 | * TreeNode *left; 11 | * TreeNode *right; 12 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | TreeNode* sortedArrayToBST(vector& nums) { 18 | TreeNode* root; 19 | root = helper(root, nums, 0, nums.size() - 1); 20 | return root; 21 | } 22 | 23 | TreeNode* helper(TreeNode* root, vector& nums, int start, int end) { 24 | if (start > end) { 25 | return NULL; 26 | } 27 | root = new TreeNode(0); 28 | root->val = nums[(start + end + 1) / 2]; 29 | root->left = helper(root->left, nums, start, (start + end + 1) / 2 - 1); 30 | root->right = helper(root->right, nums, (start + end + 1) / 2 + 1, end); 31 | return root; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /108. Convert Sorted Array to Binary Search Tree/108. Convert Sorted Array to Binary Search Tree.java: -------------------------------------------------------------------------------- 1 | /* 2 | 本题解题思路还是从递归出发,但是要结合二叉查找树的定义,每次将数组二分中间值作为根节点, 3 | 依次递归二分并将中间值赋值给根节点,最后返回根结点,递归返回的临界条件是:左索引大于右索引 4 | */ 5 | 6 | /** 7 | * Definition for a binary tree node. 8 | * struct TreeNode { 9 | * int val; 10 | * TreeNode *left; 11 | * TreeNode *right; 12 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | TreeNode* sortedArrayToBST(vector& nums) { 18 | if(nums.size()==0) 19 | return NULL; 20 | return sortedSub(nums,0,nums.size()-1); 21 | 22 | } 23 | private: 24 | TreeNode* sortedSub(vector& nums, int l, int r) { 25 | if(l>r) 26 | return NULL; 27 | int m = (l+r)/2; 28 | TreeNode* root = new TreeNode(nums[m]); 29 | root->left = sortedSub(nums,l,m-1); 30 | root->right = sortedSub(nums,m+1,r); 31 | return root; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /108. Convert Sorted Array to Binary Search Tree/Readme.txt: -------------------------------------------------------------------------------- 1 | Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 2 | 3 | For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. 4 | 5 | Example: 6 | 7 | Given the sorted array: [-10,-3,0,5,9], 8 | 9 | One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 10 | 11 | 0 12 | / \ 13 | -3 9 14 | / / 15 | -10 5 16 | 17 | 原题 18 | 19 | 给定一个升序的序列,将它转化为高度平衡的二叉搜索树。 20 | 注意点: 21 | 22 | 同一个序列转化成的二叉搜索树可能有多种 23 | 例子: 24 | 25 | 输入: nums = [1,2,3] 26 | 输出: 27 | 28 | 2 29 | / \ 30 | 1 3 31 | -------------------------------------------------------------------------------- /110. Balanced Binary Tree/110. Balanced Binary Tree.java: -------------------------------------------------------------------------------- 1 | // This is a typical tree problem that can be solve by using recursion. 2 | 3 | // Definition for binary tree 4 | class TreeNode { 5 | int val; 6 | TreeNode left; 7 | TreeNode right; 8 | 9 | TreeNode(int x) { 10 | val = x; 11 | } 12 | } 13 | 14 | public class Solution { 15 | public boolean isBalanced(TreeNode root) { 16 | if (root == null) 17 | return true; 18 | 19 | if (getHeight(root) == -1) 20 | return false; 21 | 22 | return true; 23 | } 24 | 25 | public int getHeight(TreeNode root) { 26 | if (root == null) 27 | return 0; 28 | 29 | int left = getHeight(root.left); 30 | int right = getHeight(root.right); 31 | 32 | if (left == -1 || right == -1) 33 | return -1; 34 | 35 | if (Math.abs(left - right) > 1) { 36 | return -1; 37 | } 38 | 39 | return Math.max(left, right) + 1; 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /110. Balanced Binary Tree/Readme.txt: -------------------------------------------------------------------------------- 1 | Given a binary tree, determine if it is height-balanced. 2 | 3 | For this problem, a height-balanced binary tree is defined as: 4 | 5 | a binary tree in which the depth of the two subtrees of every node never differ by more than 1. 6 | 7 | Example 1: 8 | 9 | Given the following tree [3,9,20,null,null,15,7]: 10 | 11 | 3 12 | / \ 13 | 9 20 14 | / \ 15 | 15 7 16 | Return true. 17 | 18 | Example 2: 19 | 20 | Given the following tree [1,2,2,3,3,null,null,4,4]: 21 | 22 | 1 23 | / \ 24 | 2 2 25 | / \ 26 | 3 3 27 | / \ 28 | 4 4 29 | Return false. 30 | 31 | 原题 32 | 33 | 判断一棵二叉树是否是平衡二叉树,只有当每个节点的左右两棵子树的高度差不大于1时,这棵树才是平衡的。 34 | 35 | 注意点: 36 | 37 | 无 38 | 例子: 39 | 40 | 输入: 41 | 42 | 3 43 | / \ 44 | 9 20 45 | / \ 46 | 15 7 47 | / 48 | 14 49 | 输出: False 50 | -------------------------------------------------------------------------------- /111. Minimum Depth of Binary Tree—Breadth-first Search/111. Minimum Depth of Binary Tree—Breadth-first Search.cpp: -------------------------------------------------------------------------------- 1 | //思路: 2 | //!!!递归的终止条件:遍历到叶子结点,这里极容易错误的将遍历到节点为空作为递归终止条件,从而产生错误。 3 | 4 | class Solution { 5 | public: 6 | int minDepth(TreeNode* root) { 7 | if(root == NULL) //检测第一进入的时候给定的root是否为空 8 | return 0; 9 | if(root->left == NULL && root->right == NULL) //递归终止条件 10 | return 1; 11 | int leftD = INT_MAX; //左子树的最小深度(定义为最大值是为了min函数返回不为空的子树的深度+1) 12 | int rightD = INT_MAX; //右子树的最小深度 13 | if(root->left != NULL) //左子树为空,则返回右子树的深度+1 14 | leftD = minDepth(root->left); 15 | if(root->right != NULL) //右子树为空,则返回做子树的深度+1 16 | rightD = minDepth(root->right); 17 | return min(leftD, rightD) + 1; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /111. Minimum Depth of Binary Tree—Breadth-first Search/111. Minimum Depth of Binary Tree—Breadth-first Search.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for binary tree 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode(int x) { val = x; } 8 | * } 9 | */ 10 | public class Solution { 11 | public int minDepth(TreeNode root) { 12 | if(root == null) return 0; 13 | if(root.left == null)return minDepth(root.right) + 1; 14 | if(root.right == null) return minDepth(root.left) + 1; 15 | 16 | return Math.min(minDepth(root.left), minDepth(root.right)) + 1; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /111. Minimum Depth of Binary Tree—Breadth-first Search/111. Minimum Depth of Binary Tree—Breadth-first Search.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | def minDepth(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: int 13 | """ 14 | if root == None: 15 | return 0 16 | elif root.left == None and root.right == None: 17 | return 1 18 | elif root.left == None and root.right != None: 19 | return self.minDepth(root.right)+1 20 | elif root.right ==None and root.left != None: 21 | return self.minDepth(root.left)+1 22 | elif root.left != None and root.right !=None: 23 | return min(self.minDepth(root.left), self.minDepth(root.right))+1 24 | -------------------------------------------------------------------------------- /111. Minimum Depth of Binary Tree—Breadth-first Search/Readme.txt: -------------------------------------------------------------------------------- 1 | Given a binary tree, find its minimum depth. 2 | 3 | The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 4 | 5 | Note: A leaf is a node with no children. 6 | 7 | Example: 8 | 9 | Given binary tree [3,9,20,null,null,15,7], 10 | 11 | 3 12 | / \ 13 | 9 20 14 | / \ 15 | 15 7 16 | return its minimum depth = 2. -------------------------------------------------------------------------------- /112. Path Sum/112. Path Sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 递归实现。 3 | 4 | 如果节点为空则返回false; 5 | 6 | 如果左右子节点均为空,则返回节点值是否等于sum; 7 | 8 | 否则递归判断其左右子树,新sum为sum减去节点的值。 9 | 10 | 11 | */ 12 | /** 13 | * Definition for binary tree 14 | * struct TreeNode { 15 | * int val; 16 | * TreeNode *left; 17 | * TreeNode *right; 18 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 19 | * }; 20 | */ 21 | class Solution { 22 | public: 23 | bool hasPathSum(TreeNode *root, int sum) { 24 | if(root == NULL) 25 | { 26 | return false; 27 | } 28 | 29 | if(root->left == NULL && root->right == NULL) 30 | { 31 | return sum == root->val; 32 | } 33 | 34 | return hasPathSum(root->left, sum - root->val) 35 | || hasPathSum(root->right, sum - root->val); 36 | } 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /112. Path Sum/Readme.txt: -------------------------------------------------------------------------------- 1 | Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. 2 | 3 | Note: A leaf is a node with no children. 4 | 5 | Example: 6 | 7 | Given the below binary tree and sum = 22, 8 | 9 | 5 10 | / \ 11 | 4 8 12 | / / \ 13 | 11 13 4 14 | / \ \ 15 | 7 2 1 16 | 17 | return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. 18 | 19 | 原题 20 | 21 | 判断一棵二叉树是否有一条从根节点到某一叶子节点的路径,该路径上所有节点的和为一个特定值。 22 | 注意点: 23 | 24 | 无 25 | 例子: 26 | 27 | 输入: sum = 12 28 | 3 29 | / \ 30 | 9 20 31 | / \ 32 | 15 7 33 | / 34 | 14 35 | 输出: True (3->9) 36 | -------------------------------------------------------------------------------- /121. Best Time to Buy and Sell Stock/121. Best Time to Buy and Sell Stock.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector& prices) { 4 | if (prices.empty()) { 5 | return 0; 6 | } 7 | int profit = 0; 8 | int buy = prices[0]; 9 | for (int i = 0; i < prices.size(); i++) { 10 | //截至第i天,买入的最低价格:第i-1天的价格与第i天的价格的最小值 11 | buy = min(buy, prices[i]); 12 | //截至第i天,获得的最大利润:第i-1天的利润与在第i天卖出得到的最大利润 13 | profit = max(profit, prices[i] - buy); 14 | } 15 | return profit; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /121. Best Time to Buy and Sell Stock/121. Best Time to Buy and Sell Stock.java: -------------------------------------------------------------------------------- 1 | //复杂度分析 2 | 3 | //时间复杂度:O(n)O(n)。只需要遍历一次。 4 | 5 | //空间复杂度:O(1)O(1)。只使用了两个变量。 6 | 7 | public class Solution { 8 | public int maxProfit(int prices[]) { 9 | int minprice = Integer.MAX_VALUE; 10 | int maxprofit = 0; 11 | for (int i = 0; i < prices.length; i++) { 12 | if (prices[i] < minprice) 13 | minprice = prices[i]; 14 | else if (prices[i] - minprice > maxprofit) 15 | maxprofit = prices[i] - minprice; 16 | } 17 | return maxprofit; 18 | } 19 | } -------------------------------------------------------------------------------- /121. Best Time to Buy and Sell Stock/121. Best Time to Buy and Sell Stock.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxProfit(self, prices): 3 | """ 4 | :type prices: List[int] 5 | :rtype: int 6 | """ 7 | if len(prices) < 2: 8 | return 0 9 | profit = 0 10 | minimum = prices[0] 11 | for i in prices: 12 | minimum = min(i, minimum) 13 | profit = max(i - minimum, profit) 14 | return profit -------------------------------------------------------------------------------- /121. Best Time to Buy and Sell Stock/question&solution.md: -------------------------------------------------------------------------------- 1 | #### [121. 买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) 2 | 3 | 4 | 5 | 给定一个数组,它的第 *i* 个元素是一支给定股票第 *i* 天的价格。 6 | 7 | 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。 8 | 9 | 注意你不能在买入股票前卖出股票。 10 | 11 | **示例 1:** 12 | 13 | ``` 14 | 输入: [7,1,5,3,6,4] 15 | 输出: 5 16 | 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 17 | 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。 18 | ``` 19 | 20 | **示例 2:** 21 | 22 | ``` 23 | 输入: [7,6,4,3,1] 24 | 输出: 0 25 | 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 26 | ``` -------------------------------------------------------------------------------- /123. Best Time to Buy and Sell Stock III/123. Best Time to Buy and Sell Stock III.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector &prices) { 4 | if (prices.empty()) return 0; 5 | int g[3] = {0}; 6 | int l[3] = {0}; 7 | for (int i = 0; i < prices.size() - 1; ++i) { 8 | int diff = prices[i + 1] - prices[i]; 9 | for (int j = 2; j >= 1; --j) { 10 | l[j] = max(g[j - 1] + max(diff, 0), l[j] + diff); 11 | g[j] = max(l[j], g[j]); 12 | } 13 | } 14 | return g[2]; 15 | } 16 | }; -------------------------------------------------------------------------------- /123. Best Time to Buy and Sell Stock III/123. Best Time to Buy and Sell Stock III.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxProfit(int[] prices) { 3 | int b1=Integer.MIN_VALUE,b2=Integer.MIN_VALUE; 4 | int s1=0,s2=0; 5 | 6 | for(int i=0;i 2 | #include "ctype.h" 3 | using namespace std; 4 | 5 | bool isPalindrome(string s) 6 | { 7 | int first,last; 8 | first = 0; 9 | last = s.size() - 1; 10 | while (first <= last) 11 | { 12 | while (!(isalnum(s[first])) && first < last) 13 | { 14 | first++; 15 | } 16 | while (!(isalnum(s[last])) && first < last) 17 | { 18 | last--; 19 | } 20 | if (toupper(s[first]) != toupper(s[last])) 21 | { 22 | return false; 23 | } 24 | first++; 25 | last--; 26 | } 27 | return true; 28 | } 29 | 30 | void main() 31 | { 32 | string s = "A man, a plan, a canal: Panama"; 33 | bool m = isPalindrome(s); 34 | cout << m << endl; 35 | system("pause"); 36 | } -------------------------------------------------------------------------------- /125.Valid Palindrome/readme.md: -------------------------------------------------------------------------------- 1 | #### [125. 验证回文串](https://leetcode-cn.com/problems/valid-palindrome/) 2 | 3 | 难度简单 4 | 5 | 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 6 | 7 | **说明:**本题中,我们将空字符串定义为有效的回文串。 8 | 9 | **示例 1:** 10 | 11 | ``` 12 | 输入: "A man, a plan, a canal: Panama" 13 | 输出: true 14 | ``` 15 | 16 | **示例 2:** 17 | 18 | ``` 19 | 输入: "race a car" 20 | 输出: false 21 | ``` 22 | 23 | 125. Valid Palindrome 24 | 25 | Easy 26 | 27 | Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. 28 | 29 | **Note:** For the purpose of this problem, we define empty string as valid palindrome. 30 | 31 | **Example 1:** 32 | 33 | ``` 34 | Input: "A man, a plan, a canal: Panama" 35 | Output: true 36 | ``` 37 | 38 | **Example 2:** 39 | 40 | ``` 41 | Input: "race a car" 42 | Output: false 43 | ``` -------------------------------------------------------------------------------- /139.Word Break/139.Word Break.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool wordBreak(string s, vector& wordDict) { 4 | int len=s.size(); 5 | vector isWordBreak(len+1,false);//定义一个含有len+1个元素的vector,用于存储子问题信息 6 | isWordBreak[0]=true;//将第一个元素设置为true,表示当字符串为空的时候也成立 7 | set dict; 8 | 9 | for(const auto &ss:wordDict) dict.insert(ss); 10 | 11 | for(int i=0;i wordDict) { 3 | boolean[] dp = new boolean[s.length() + 1]; 4 | dp[0] = true; 5 | for (int i = 1; i <= s.length(); i++) { 6 | for (int j = i - 1; j >= 0 && !dp[i]; j--) { 7 | String check = s.substring(j, i); 8 | dp[i] = dp[j] && wordDict.contains(check); 9 | } 10 | } 11 | return dp[s.length()]; 12 | } 13 | } -------------------------------------------------------------------------------- /139.Word Break/139.Word Break.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def wordBreak(self, s, wordDict): 3 | """ 4 | :type s: str 5 | :type wordDict: List[str] 6 | :rtype: bool 7 | """ 8 | return self._wordBreak(s, set(wordDict), 0, set()) 9 | 10 | def _wordBreak(self, s, words, start, mem): 11 | if start == len(s): 12 | return True 13 | 14 | if start in mem: 15 | return False 16 | 17 | for i in range(start + 1, len(s) + 1): 18 | if i in mem: 19 | continue 20 | 21 | sub = s[start:i] 22 | if sub in words and self._wordBreak(s, words, i, mem): 23 | return True 24 | 25 | mem.add(start) 26 | return False 27 | -------------------------------------------------------------------------------- /140. Word Break II/140. Word Break II.java: -------------------------------------------------------------------------------- 1 | List result; 2 | public List wordBreak(String s, Set wordDict) { 3 | result = new ArrayList(); 4 | int n = s.length(); 5 | //对每一个i都形成一个可以跳跃的点 6 | List[] pointer = new List[n]; 7 | for(int i=0;i(); 8 | //动态规划形成跳跃点 9 | for(int i=0;i0)) 13 | pointer[i].add(j); 14 | } 15 | } 16 | //从后往前的递归 17 | helper(pointer, s, n-1, ""); 18 | return result; 19 | } 20 | //DFS 21 | public void helper(List[] pointer, String s, int i, String pattern){ 22 | if(i<0){ 23 | result.add(pattern); 24 | return; 25 | } 26 | for(Integer item:pointer[i]){ 27 | String nextPattern = pattern.length()==0?s.substring(item,i+1):s.substring(item,i+1)+" "+pattern; 28 | helper(pointer, s, item-1, nextPattern); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /141.Linked List Cycle/141.Linked List Cycle.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool hasCycle(ListNode *head) { 4 | ListNode* first=head; 5 | ListNode* second=head; 6 | while(first!=NULL&&second!=NULL&&second->next!=NULL){ //注意这个条件判断不能写漏了。 7 | first=first->next; 8 | second=second->next->next; 9 | if(first==second) 10 | return true; 11 | } 12 | return false; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /141.Linked List Cycle/141.Linked List Cycle.java: -------------------------------------------------------------------------------- 1 | 题目要求是判断链表是否有环,leetcode上链表的题都是没有头结点的,这点大家要记住。而且若链表有环,也是最后一个节点形成的环。 2 | 3 | 大家考虑这样一个问题,链表的环相当于一个圆形操场。假设有两个人在圆形操场上无限循环的跑,那么速度快的一定能追得上速度慢的。 4 | 同理,若要判断一个链表是否有环,可设计快慢指针,当快慢指针都进入环的时候,若最终两个指针相遇,必可说明链表存在环。 5 | 下面就要考虑快慢指针的步长,从跑操场的情况来看,不管慢的有多慢,快得有多快,最终肯定能相遇。同理,链表中,也可随意指定快慢指针的步长,无非就是跑的圈数多少的问题 6 | 7 | * Definition for singly-linked list. 8 | * class ListNode { 9 | * int val; 10 | * ListNode next; 11 | * ListNode(int x) { 12 | * val = x; 13 | * next = null; 14 | * } 15 | * } 16 | */ 17 | public class Solution { 18 | public boolean hasCycle(ListNode head) { 19 | ListNode p=head;//快指针 20 | ListNode q=head;//慢指针 21 | while(p!=null&&q!=null&&p.next!=null){//边界条件是出现空指针,就返回false; 22 | q=q.next; 23 | p=p.next.next;//空指针没有next,否则会出现NullPointerException问题 24 | if(p==q)return true; 25 | } 26 | return false; 27 | } 28 | } 29 | 30 | reference: 31 | https://blog.csdn.net/shuaishuai3409/article/details/51434182 32 | -------------------------------------------------------------------------------- /142.Linked List Cycle II/142.Linked List Cycle II.py.md: -------------------------------------------------------------------------------- 1 | ![img](https://img-blog.csdn.net/20180925213445926?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1N1bl9XaGl0ZV9Cb3k=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) 2 | 3 | 链表中存在环,由上图可知快节点走过的路径是a,b,c,d,b,c;慢节点走过的路径是a,b,c 4 | 又因为快节点速度是慢节点的两倍,所以可知a+b+c+d+b+c = 2a+2b+2c 5 | d+b+c = a+b+c 6 | d(相遇点距环入口的距离) = a(头节点距环入口的距离) 7 | 再看第一种情况,可以知道,快节点是慢节点的多少倍,快节点就通过多少圈与慢节点相遇。 8 | 所以就根据相遇点距环入口的距离等于头节点距环入口的距离 9 | 10 | ```python 11 | class Solution(object): 12 | def detectCycle(self, head): 13 | """ 14 | :type head: ListNode 15 | :rtype: ListNode 16 | """ 17 | if head is None: 18 | return None 19 | if head.next is None: 20 | return None 21 | first = second = head 22 | while second.next and second.next.next: 23 | first = first.next 24 | second = second.next.next 25 | if first == second: 26 | p = head 27 | while first != p: 28 | p = p.next 29 | first = first.next 30 | return p 31 | return None 32 | ``` 33 | 34 | ---------------------Quote-----https://blog.csdn.net/sun_white_boy/article/details/82845791 --- -------------------------------------------------------------------------------- /202. Happy Number/202. Happy Number.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 按照题目的描述,需要循环求平方和,即求出当前数组的平方和后,再以此平方和作为新的数继续求平方和, 3 | 而循环终止条件是:得到的平方和为1,或得到的平方和在之前的循环中出现过。判断平方和是否为1很简单, 4 | 每次检查就好了;而判断平方和是否出现过,则只需要维持一个Set,每次循环检查当前平方和是否在Set中, 5 | 在则终止循环,不在则将此平方和放到Set中。 6 | 7 | */ 8 | 9 | class Solution { 10 | public: 11 | bool isHappy(int n) { 12 | set got; 13 | while (n != 1 && got.find(n) == got.end()) { 14 | got.insert(n); 15 | int sum = 0; 16 | while (n) { 17 | sum += pow(n % 10, 2); 18 | n /= 10; 19 | } 20 | n = sum; 21 | } 22 | return n == 1; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /202. Happy Number/202. Happy Number.java: -------------------------------------------------------------------------------- 1 | /* 2 | 按照题目的描述,需要循环求平方和,即求出当前数组的平方和后,再以此平方和作为新的数继续求平方和,而循环终止条件是: 3 | 得到的平方和为1,或得到的平方和在之前的循环中出现过。判断平方和是否为1很简单,每次检查就好了;而判断平方和是否出现过, 4 | 则只需要维持一个Set,每次循环检查当前平方和是否在Set中,在则终止循环,不在则将此平方和放到Set中。 5 | 6 | */ 7 | 8 | public class Solution { 9 | public boolean isHappy(int n) { 10 | Set got = new HashSet<>(); 11 | while (n != 1 && !got.contains(n)) { 12 | got.add(n); 13 | int sum = 0; 14 | while (n != 0) { 15 | sum += Math.pow(n % 10, 2); 16 | n /= 10; 17 | } 18 | n = sum; 19 | } 20 | return n == 1; 21 | } 22 | } 23 | 24 | 25 | //方法二 by 初夏大佬 26 | 27 | class Solution { 28 | public int reverse(int x) { 29 | if((x<=0 && x>-10)||(x<10&&x>0)){ 30 | return x; 31 | } 32 | 33 | long result = 0; 34 | while(x != 0 ){ 35 | result = result*10 + x%10; 36 | x = x/10; 37 | } 38 | 39 | if(result <= Integer.MIN_VALUE || result >= Integer.MAX_VALUE){ 40 | return 0; 41 | } 42 | 43 | return (int)result; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /202. Happy Number/Readme.md: -------------------------------------------------------------------------------- 1 | Write an algorithm to determine if a number is "happy". 2 | 3 | A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers. 4 | 5 | Example: 6 | 7 | Input: 19 8 | 9 | Output: true 10 | 11 | Explanation: 12 | 13 | 1^2 + 9^2 = 82 14 | 15 | 8^2 + 2^2 = 68 16 | 17 | 6^2 + 8^2 = 100 18 | 19 | 1^2 + 0^2 + 0^2 = 1 20 | 21 | 写一个程序来判断一个数字是否是“happy”的。 22 | 23 | 所谓 happy number,是被这样的过程定义的数字:初始时有一个正整数,用该整数每位数字的平方之和代替这个整数,重复该过程直至数字变为1(之后不再变化),或者陷入一个无尽的循环但该循环不包括1。那些能终止于1的数字就称为 happy number。 24 | 25 | 比如:19就是一个 happy number,因为 26 | 27 | 1^2 + 9^2 = 82 28 | 29 | 8^2 + 2^2 = 68 30 | 31 | 6^2 + 8^2 = 100 32 | 33 | 1^2 + 0^2 + 0^2 = 1 34 | -------------------------------------------------------------------------------- /204. Count Primes/204. Count Primes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 朴素的判断必定超时,我们每次判断一个数是素数的时候,就将它的倍数标记为非素数即可。 3 | */ 4 | 5 | class Solution { 6 | public: 7 | int countPrimes(int n) { 8 | if (n <= 2) return 0; 9 | bool * isPrimer = new bool[n]; 10 | for (int i = 0; i < n; i++) isPrimer[i] = true; 11 | for (int i = 2; i * i < n; i++) { 12 | if (isPrimer[i]) 13 | for (int j = i ; j * i < n; j ++) 14 | isPrimer[j * i] = false; 15 | } 16 | int res = 0; 17 | for (int i = 2; i < n; i++) 18 | if (isPrimer[i]) res++; 19 | delete[] isPrimer; 20 | return res; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /204. Count Primes/Readme.md: -------------------------------------------------------------------------------- 1 | Count the number of prime numbers less than a non-negative number, n. 2 | 3 | Example: 4 | 5 | Input: 10 6 | Output: 4 7 | Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7. 8 | 9 | 10 | 计算小于非负数n的素数的数量。 11 | 12 | 例: 13 | 14 | 输入: 10 15 | 输出: 4 16 | 说明:有4个素数小于10,它们是2,3,5,7。 17 | -------------------------------------------------------------------------------- /215. Kth Largest Element in an Array/215. Kth Largest Element in an Array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int findKthLargest(vector& nums, int k) { 4 | priority_queue p; 5 | for(auto n:nums){ 6 | p.push(n); 7 | } 8 | for(int i = 0; i < k-1; i++){ 9 | p.pop(); 10 | } 11 | return p.top(); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /215. Kth Largest Element in an Array/215. Kth Largest Element in an Array.py: -------------------------------------------------------------------------------- 1 | #解题思路:利用快速排序的思想。每次找一半。最坏情况O(N2),平均时间O(N)。 2 | class Solution(object): 3 | def findKthLargest(self, nums, k): 4 | """ 5 | :type nums: List[int] 6 | :type k: int 7 | :rtype: int 8 | """ 9 | return self.find(nums,k-1,0,len(nums)-1) 10 | def find(self,nums,k,left,right): 11 | l = left 12 | r = right 13 | partition = nums[(left+right)/2] 14 | while(left<=right):#结束条件是left大于right,否则有可能需要交换 15 | while(nums[left]>partition): 16 | left += 1 17 | while(nums[right]= k and right>l: 24 | #说明在右半边 25 | return self.find(nums,k,l,right) 26 | if left <= k and left& nums) { 19 | //遍历数组,查看数组中的数是否在set中,如果不在,将数组中的数存储到set中,如果在,有重复,返回false 20 | if(nums.size() == 0) return false; 21 | if(nums.size() == 1) return false; 22 | 23 | set cpnums; 24 | for(int i = 0; i < nums.size(); i ++){ 25 | if(cpnums.find(nums[i]) != cpnums.end()) 26 | return true; 27 | else{ 28 | cpnums.insert(nums[i]); 29 | } 30 | } 31 | return false; 32 | } 33 | }; 34 | 35 | 36 | /* 37 | 方法二: 38 | 39 | 可以先将数组排序,然后判断相邻的两个数是否有相等的,有,说明有重复,返回true。 40 | 41 | 时间复杂度:O(n) 42 | 43 | 空间复杂度:O(1) 44 | 45 | */ 46 | 47 | class Solution { 48 | public: 49 | bool containsDuplicate(vector& nums) { 50 | sort(nums.begin(), nums.end()); 51 | for(int i = 1; i < nums.size(); i ++){ 52 | if(nums[i] == nums[i - 1]) 53 | return true; 54 | } 55 | return false; 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /217. Contains Duplicate/217. Contains Duplicate.java: -------------------------------------------------------------------------------- 1 | 2 | //这道题不算难题,就是使用一个哈希表,遍历整个数组,如果哈希表里存在,返回false,如果不存在,则将其放入哈希表中 3 | 4 | //方法一 5 | class Solution { 6 | public: 7 | bool containsDuplicate(vector& nums) { 8 | unordered_map m; 9 | for (int i = 0; i < nums.size(); ++i) { 10 | if (m.find(nums[i]) != m.end()) return true; 11 | ++m[nums[i]]; 12 | } 13 | return false; 14 | } 15 | }; 16 | 17 | 18 | // 方法二 19 | //先将数组排个序,然后再比较相邻两个数字是否相等,时间复杂度取决于排序方法 20 | 21 | class Solution { 22 | public: 23 | bool containsDuplicate(vector& nums) { 24 | sort(nums.begin(), nums.end()); 25 | for (int i = 1; i < nums.size(); ++i) { 26 | if (nums[i] == nums[i - 1]) return true; 27 | } 28 | return false; 29 | } 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /217. Contains Duplicate/217. Contains Duplicate.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def containsDuplicate(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: bool 6 | """ 7 | return len(nums) != len(set(nums)) 8 | 9 | 10 | if __name__ == "__main__": 11 | assert Solution().containsDuplicate([1, 2, 3, 4]) == False 12 | assert Solution().containsDuplicate([1, 2, 3, 1]) == True 13 | -------------------------------------------------------------------------------- /217. Contains Duplicate/Readme.md: -------------------------------------------------------------------------------- 1 | Given an array of integers, find if the array contains any duplicates. 2 | 3 | Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. 4 | 5 | Example 1: 6 | 7 | Input: [1,2,3,1] 8 | Output: true 9 | Example 2: 10 | 11 | Input: [1,2,3,4] 12 | Output: false 13 | Example 3: 14 | 15 | Input: [1,1,1,3,3,4,3,2,4,2] 16 | Output: true 17 | 18 | 19 | 给定一个整数数组,查找数组是否包含任何重复项。 20 | 21 | 如果数组中任何值至少出现两次,则函数应返回true,如果每个元素都不相同,则返回false。 22 | 23 | 例1: 24 | 25 | 输入: [1,2,3,1] 26 | 输出: true 27 | 例2: 28 | 29 | 输入: [1,2,3,4] 30 | 输出: false 31 | 例3: 32 | 33 | 输入: [1,1,1,3,3,4,3,2,4,2] 34 | 输出: true 35 | -------------------------------------------------------------------------------- /225. Implement Stack using Queues/readme.md: -------------------------------------------------------------------------------- 1 | Implement the following operations of a stack using queues. 2 | 3 | push(x) -- Push element x onto stack. 4 | 5 | pop() -- Removes the element on top of the stack. 6 | 7 | top() -- Get the top element. 8 | 9 | empty() -- Return whether the stack is empty. 10 | 11 | Example: 12 | 13 | MyStack stack = new MyStack(); 14 | 15 | stack.push(1); 16 | 17 | stack.push(2); 18 | 19 | stack.top(); // returns 2 20 | 21 | stack.pop(); // returns 2 22 | 23 | stack.empty(); // returns false 24 | 25 | Notes: 26 | 27 | You must use only standard operations of a queue -- which means only push to back, peek/pop from front, size, and is empty operations are valid. 28 | Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue. 29 | You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). 30 | 31 | ![image](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/225.%20Implement%20Stack%20using%20Queues.png) 32 | -------------------------------------------------------------------------------- /232. Implement Queue using Stacks/232. Implement Queue using Stacks.cpp: -------------------------------------------------------------------------------- 1 | class Queue { 2 | public: 3 | // Push element x to the back of queue. 4 | void push(int x) { 5 | stack tmp; 6 | while (!s.empty()) { 7 | tmp.push(s.top()); 8 | s.pop(); 9 | } 10 | s.push(x); 11 | while (!tmp.empty()) { 12 | s.push(tmp.top()); 13 | tmp.pop(); 14 | } 15 | } 16 | 17 | // Removes the element from in front of queue. 18 | void pop(void) { 19 | s.pop(); 20 | } 21 | 22 | // Get the front element. 23 | int peek(void) { 24 | return s.top(); 25 | } 26 | 27 | // Return whether the queue is empty. 28 | bool empty(void) { 29 | return s.empty(); 30 | } 31 | 32 | private: 33 | stack s; 34 | }; 35 | 36 | 37 | 38 | //方法二 by多年未见 39 | class Solution 40 | { 41 | public: 42 | void push(int node) { 43 | stack2.push(node); 44 | } 45 | 46 | int pop() { 47 | if (stack1.empty()) { 48 | while (!stack2.empty()) { 49 | stack1.push(stack2.top()); 50 | stack2.pop(); 51 | } 52 | } 53 | int tmp = stack1.top(); 54 | stack1.pop(); 55 | return tmp; 56 | } 57 | 58 | private: 59 | stack stack1; 60 | stack stack2; 61 | }; 62 | -------------------------------------------------------------------------------- /232. Implement Queue using Stacks/232. Implement Queue using Stacks.java: -------------------------------------------------------------------------------- 1 | class MyQueue { 2 | 3 | Stack temp = new Stack(); 4 | Stack value = new Stack(); 5 | 6 | // Push element x to the back of queue. 7 | public void push(int x) { 8 | if(value.isEmpty()){ 9 | value.push(x); 10 | }else{ 11 | while(!value.isEmpty()){ 12 | temp.push(value.pop()); 13 | } 14 | 15 | value.push(x); 16 | 17 | while(!temp.isEmpty()){ 18 | value.push(temp.pop()); 19 | } 20 | } 21 | } 22 | 23 | // Removes the element from in front of queue. 24 | public void pop() { 25 | value.pop(); 26 | } 27 | 28 | // Get the front element. 29 | public int peek() { 30 | return value.peek(); 31 | } 32 | 33 | // Return whether the queue is empty. 34 | public boolean empty() { 35 | return value.isEmpty(); 36 | } 37 | }   38 | -------------------------------------------------------------------------------- /232. Implement Queue using Stacks/readme.md: -------------------------------------------------------------------------------- 1 | Implement the following operations of a queue using stacks. 2 | 3 | push(x) -- Push element x to the back of queue. 4 | 5 | pop() -- Removes the element from in front of queue. 6 | 7 | peek() -- Get the front element. 8 | 9 | empty() -- Return whether the queue is empty. 10 | 11 | Example: 12 | 13 | MyQueue queue = new MyQueue(); 14 | 15 | queue.push(1); 16 | 17 | queue.push(2); 18 | 19 | queue.peek(); // returns 1 20 | 21 | queue.pop(); // returns 1 22 | 23 | queue.empty(); // returns false 24 | 25 | Notes: 26 | 27 | You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, 28 | and is empty operations are valid. 29 | 30 | Depending on your language, stack may not be supported natively. 31 | 32 | You may simulate a stack by using a list or deque (double-ended queue), 33 | 34 | as long as you use only standard operations of a stack. 35 | 36 | You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). 37 | 38 | ![image](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/Implement%20Queue%20using%20Stacks.png) 39 | -------------------------------------------------------------------------------- /303.Range Sum Query - Immutable/303.Range Sum Query - Immutable.cpp: -------------------------------------------------------------------------------- 1 | class NumArray { 2 | public: 3 | NumArray(vector nums) { 4 | dp.resize(nums.size()+1,0); 5 | for(int i=1;i<=nums.size();++i){ 6 | dp[i] = dp[i-1]+nums[i-1]; 7 | } 8 | } 9 | 10 | int sumRange(int i, int j) { 11 | return dp[j+1]-dp[i]; 12 | } 13 | private: 14 | vector dp; 15 | }; 16 | -------------------------------------------------------------------------------- /303.Range Sum Query - Immutable/303.Range Sum Query - Immutable.java: -------------------------------------------------------------------------------- 1 | public NumArray(int[] nums) { 2 |      //nums[0]不变 num[i]=num[i]+前一位 3 | for(int i = 1; i < nums.length; i++){ 4 | nums[i] =nums[i]+nums[i - 1]; 5 | } 6 | 7 | this.nums = nums; 8 | } 9 | 10 | public int sumRange(int i, int j) { 11 | if(i == 0){ 12 | return nums[j]; 13 | } 14 | 15 | return nums[j] - nums[i - 1]; 16 | } -------------------------------------------------------------------------------- /303.Range Sum Query - Immutable/303.Range Sum Query - Immutable.md: -------------------------------------------------------------------------------- 1 | 因为题目中的条件**数组不可变**,所以对于这个问题其实有一个更好的思路。例如 2 | 3 | ![img](http://wx2.sinaimg.cn/mw690/af2d2659ly1fz01nug4vjj20a700sjr5.jpg) 4 | 5 | 然后我们将数不断向后累加。 6 | 7 | ![img](http://wx2.sinaimg.cn/mw690/af2d2659ly1fz02ao3k0mj20b0035t8i.jpg) 8 | 9 | 当我们要求`[left,right]`区间内的和的时候,我们只需要用`sum[right]-sum[left-1]`即可。 10 | 11 | class NumArray: 12 | 13 | ```python 14 | def __init__(self, nums): 15 | """ 16 | :type nums: List[int] 17 | """ 18 | self.nums = [0]+nums 19 | for i in range(len(self.nums)): 20 | self.nums[i] += self.nums[i-1] 21 | 22 | def sumRange(self, i, j): 23 | """ 24 | :type i: int 25 | :type j: int 26 | :rtype: int 27 | """ 28 | return self.nums[j+1] - self.nums[i] 29 | ``` 30 | --------------------- 31 | -------------------------------------------------------------------------------- /303.Range Sum Query - Immutable/303.Range Sum Query - Immutable.py: -------------------------------------------------------------------------------- 1 | class NumArray: 2 | 3 | def __init__(self, nums): 4 | """ 5 | :type nums: List[int] 6 | """ 7 | self.nums = [0]+nums 8 | for i in range(len(self.nums)): 9 | self.nums[i] += self.nums[i-1] 10 | 11 | def sumRange(self, i, j): 12 | """ 13 | :type i: int 14 | :type j: int 15 | :rtype: int 16 | """ 17 | return self.nums[j+1] - self.nums[i] -------------------------------------------------------------------------------- /304. Range Sum Query 2D - Immutable/304. Range Sum Query 2D - Immutable.java: -------------------------------------------------------------------------------- 1 | class NumMatrix { 2 | 3 | int[][] sum; 4 | int m; 5 | int n; 6 | 7 | public NumMatrix(int[][] matrix) { 8 | if(matrix == null) return; 9 | this.m = matrix.length; 10 | if(m==0) return; 11 | this.n = matrix[0].length; 12 | if(n == 0) return ; 13 | sum = new int[m][n]; 14 | for(int i = 0 ; i < m ; i++){ 15 | for(int j = 0; j < n ; j++){ 16 | if(i > 0) sum[i][j] += sum[i-1][j]; 17 | if(j > 0) sum[i][j] += sum[i][j-1]; 18 | sum[i][j] += matrix[i][j]; 19 | if(i > 0 && j > 0) sum[i][j] -= sum[i-1][j-1]; 20 | } 21 | } 22 | } 23 | 24 | public int sumRegion(int row1, int col1, int row2, int col2) { 25 | if(sum == null) return 0; 26 | if(row1 > m || row2 > m || col1 > n || col2 > n) return 0; 27 | int ans = sum[row2][col2]; 28 | if(row1>0) ans -= sum[row1-1][col2]; 29 | if(col1>0) ans -= sum[row2][col1-1]; 30 | if(row1 > 0 && col1 >0) ans += sum[row1-1][col1-1]; 31 | return ans; 32 | } 33 | } 34 | 35 | /** 36 | * Your NumMatrix object will be instantiated and called as such: 37 | * NumMatrix obj = new NumMatrix(matrix); 38 | * int param_1 = obj.sumRegion(row1,col1,row2,col2); 39 | */ 40 | -------------------------------------------------------------------------------- /304. Range Sum Query 2D - Immutable/304. Range Sum Query 2D - Immutable.py: -------------------------------------------------------------------------------- 1 | 执行用时为 48 ms 的范例 2 | class NumMatrix(object): 3 | 4 | def __init__(self, matrix): 5 | """ 6 | :type matrix: List[List[int]] 7 | """ 8 | if not matrix or not matrix[0]: 9 | M, N = 0, 0 10 | else: 11 | M, N = len(matrix), len(matrix[0]) 12 | self.sumM = [[0] * (N + 1) for _ in range(M + 1)] 13 | for i in range(M): 14 | for j in range(N): 15 | self.sumM[i + 1][j + 1] = self.sumM[i][j + 1] + self.sumM[i + 1][j] - self.sumM[i][j] + matrix[i][j] 16 | 17 | def sumRegion(self, row1, col1, row2, col2): 18 | """ 19 | :type row1: int 20 | :type col1: int 21 | :type row2: int 22 | :type col2: int 23 | :rtype: int 24 | """ 25 | return self.sumM[row2 + 1][col2 + 1] - self.sumM[row2 + 1][col1] - self.sumM[row1][col2 + 1] + self.sumM[row1][col1] 26 | 27 | 28 | 29 | # Your NumMatrix object will be instantiated and called as such: 30 | # obj = NumMatrix(matrix) 31 | # param_1 = obj.sumRegion(row1,col1,row2,col2) -------------------------------------------------------------------------------- /344.Reverse String/344.Reverse String.cpp: -------------------------------------------------------------------------------- 1 | #耗时64ms 2 | #递归 逐个逆转 3 | class Solution(object): 4 | def reverseString(s): 5 | if len(s) <=1: 6 | return s 7 | return self.reverseString(s[1:]) + s[0] 8 | 9 | #耗时52ms 10 | #前后对称位互换 11 | class Solution(object): 12 | def reverseString(s): 13 | li = list(s) 14 | l = len(s) 15 | for i, j in zip(range(len(l)-1, 0, -1), range(l//2)): 16 | li[i], li[j] = li[j], li[i] 17 | reurn ''.join(li) 18 | 19 | #耗时52ms 20 | #循环逆序 21 | class Solution(object): 22 | def reverseString(s): 23 | return ''.join([s[i] for i in range(len(s)-1,-1,-1)]) -------------------------------------------------------------------------------- /344.Reverse String/344.Reverse String.java: -------------------------------------------------------------------------------- 1 | 2 | public class Solution { 3 | public String reverseString(String s) { 4 | StringBuilder sb = new StringBuilder(); 5 | for(int i=s.length()-1;i>=0;i--){ 6 | sb.append(s.charAt(i)); 7 | } 8 | return sb.toString(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /344.Reverse String/344.Reverse String.py: -------------------------------------------------------------------------------- 1 | 执行用时为 48 ms 的范例 2 | class NumMatrix(object): 3 | 4 | def __init__(self, matrix): 5 | """ 6 | :type matrix: List[List[int]] 7 | """ 8 | if not matrix or not matrix[0]: 9 | M, N = 0, 0 10 | else: 11 | M, N = len(matrix), len(matrix[0]) 12 | self.sumM = [[0] * (N + 1) for _ in range(M + 1)] 13 | for i in range(M): 14 | for j in range(N): 15 | self.sumM[i + 1][j + 1] = self.sumM[i][j + 1] + self.sumM[i + 1][j] - self.sumM[i][j] + matrix[i][j] 16 | 17 | def sumRegion(self, row1, col1, row2, col2): 18 | """ 19 | :type row1: int 20 | :type col1: int 21 | :type row2: int 22 | :type col2: int 23 | :rtype: int 24 | """ 25 | return self.sumM[row2 + 1][col2 + 1] - self.sumM[row2 + 1][col1] - self.sumM[row1][col2 + 1] + self.sumM[row1][col1] 26 | 27 | 28 | 29 | # Your NumMatrix object will be instantiated and called as such: 30 | # obj = NumMatrix(matrix) 31 | # param_1 = obj.sumRegion(row1,col1,row2,col2) -------------------------------------------------------------------------------- /344.Reverse String/readme.md: -------------------------------------------------------------------------------- 1 | #### LeetCode344. 反转字符串 2 | 3 | 4 | 5 | 请编写一个函数,其功能是将输入的字符串反转过来。 6 | 7 | **示例:** 8 | 9 | ``` 10 | 输入:s = "hello" 11 | 返回:"olleh" 12 | ``` 13 | 14 | 15 | 16 | 344. Reverse String 17 | 18 | Write a function that reverses a string. The input string is given as an array of characters `char[]`. 19 | 20 | Do not allocate extra space for another array, you must do this by **modifying the input array in-place** with O(1) extra memory. 21 | 22 | You may assume all the characters consist of [printable ascii characters](https://en.wikipedia.org/wiki/ASCII#Printable_characters). 23 | 24 | 25 | 26 | **Example 1:** 27 | 28 | ``` 29 | Input: ["h","e","l","l","o"] 30 | Output: ["o","l","l","e","h"] 31 | ``` 32 | 33 | **Example 2:** 34 | 35 | ``` 36 | Input: ["H","a","n","n","a","h"] 37 | Output: ["h","a","n","n","a","H"] 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /346.Moving Average from Data Stream/346.Moving Average from Data Stream.cpp: -------------------------------------------------------------------------------- 1 | class MovingAverage { 2 | public: 3 | /** Initialize your data structure here. */ 4 | MovingAverage(int size): len(size), sum(0) { 5 | } 6 | 7 | double next(int val) { 8 | sum += val; 9 | que.push(val); 10 | if(que.size() > len) 11 | { 12 | sum -= que.front(); 13 | que.pop(); 14 | } 15 | return sum/que.size(); 16 | } 17 | private: 18 | int len; 19 | double sum; 20 | queue que; 21 | }; 22 | 23 | /** 24 | * Your MovingAverage object will be instantiated and called as such: 25 | * MovingAverage obj = new MovingAverage(size); 26 | * double param_1 = obj.next(val); 27 | */ 28 | -------------------------------------------------------------------------------- /353.Design Snake Game/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/353.Design Snake Game/readme.txt -------------------------------------------------------------------------------- /387.First Unique Character in a String/387.First Unique Character in a String.cpp: -------------------------------------------------------------------------------- 1 | class Solution 2 | { 3 | public: 4 | int firstUniqChar(string s) 5 | { 6 | unordered_map m; 7 | for (char c : s) 8 | m[c]++; 9 | for (int i = 0; i < s.size(); ++i) 10 | { 11 | if (m[s[i]] == 1) 12 | return i; 13 | } 14 | return -1; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /387.First Unique Character in a String/387.First Unique Character in a String.java: -------------------------------------------------------------------------------- 1 | 1,找第一个出现一次的字符时候,从计数数组出发,找到计数为1的。定义一个变量记录位置最小值,最后返回。(这种方向适合字符串大的)。 2 | 3 | public static int firstUniqChar(String s) { 4 | int[] num = new int[26]; 5 | boolean flag = true; 6 | int min = s.length(); 7 | for(int i=0;i= nums[index]: 23 | index += 1 24 | if index == len(nums): 25 | answer.append(-1) 26 | else: 27 | answer.append(nums[index]) 28 | return answer 29 | -------------------------------------------------------------------------------- /503. Next Greater Element II/503. Next Greater Element II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector nextGreaterElements(vector& nums) { 4 | const int N = nums.size(); 5 | vector res(N, -1); 6 | stack stack; 7 | for (int i = 0; i < N * 2; i++) { 8 | while (!stack.empty() && nums[stack.top()] < nums[i % N]) { 9 | res[stack.top()] = nums[i % N]; 10 | stack.pop(); 11 | } 12 | if (i < N) 13 | stack.push(i); 14 | } 15 | return res; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /503. Next Greater Element II/readme.md: -------------------------------------------------------------------------------- 1 | Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number. 2 | 3 | Example 1: 4 | 5 | Input: [1,2,1] 6 | 7 | Output: [2,-1,2] 8 | 9 | Explanation: The first 1's next greater number is 2; 10 | 11 | The number 2 can't find next greater number; 12 | 13 | The second 1's next greater number needs to search circularly, which is also 2. 14 | 15 | Note: The length of given array won't exceed 10000. 16 | 17 | 18 | 给定一个圆形数组(最后一个元素的下一个元素是数组的第一个元素),为每个元素打印Next Greater Number。下一个更大的数字x是数组中下一个遍历顺序的第一个更大的数字,这意味着您可以循环搜索以查找其下一个更大的数字。如果它不存在,则为此数字输出-1。 19 | 20 | 例1: 21 | 22 | 输入: [1,2,1] 23 | 24 | 输出: [2,-1,2] 25 | 26 | 说明:第一个1的下一个更大的数字是2; 27 | 28 | 数字2找不到下一个更大的数字; 29 | 30 | 第二个1的下一个更大的数字需要循环搜索,这也是2。 31 | 32 | 注意: 给定数组的长度不超过10000。 33 | -------------------------------------------------------------------------------- /575. Distribute Candies/575. Distribute Candies.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 思路 3 | 这题换一个表达方式就是:一个数组,划分为元素个数相等的两份,使得其中一份中元素的值尽可能不相同。 4 | 5 | 这里一个关键点在于“不同值的个数”和“子数组长度”的关系。例如[1, 2, 3, 4]的“不同值的个数”是4,“子数组长度”是2,很显然无论如何划分都是最优解(如[1, 2]),即2;再例如[1, 1, 2, 2, 2, 2]的“不同值的个数”是2,“子数组长度”是3,最优的划分是[1, 1, 2]或[1, 2, 2],即2。 6 | 7 | 这样答案就呼之欲出了:“不同值的个数” > “子数组长度” ? “子数组长度” : “不同值的个数”。 8 | 9 | */ 10 | 11 | class Solution { 12 | public: 13 | int distributeCandies(vector &candies) { 14 | unordered_set nums = unordered_set(candies.begin(), candies.end()); 15 | int numNums = nums.size(); 16 | int numTarget = candies.size() / 2; 17 | return numNums >= numTarget ? numTarget : numNums; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /575. Distribute Candies/575. Distribute Candies.java: -------------------------------------------------------------------------------- 1 | /* 2 | 思路 3 | 这题换一个表达方式就是:一个数组,划分为元素个数相等的两份,使得其中一份中元素的值尽可能不相同。 4 | 5 | 这里一个关键点在于“不同值的个数”和“子数组长度”的关系。例如[1, 2, 3, 4]的“不同值的个数”是4,“子数组长度”是2,很显然无论如何划分都是最优解(如[1, 2]),即2;再例如[1, 1, 2, 2, 2, 2]的“不同值的个数”是2,“子数组长度”是3,最优的划分是[1, 1, 2]或[1, 2, 2],即2。 6 | 7 | 这样答案就呼之欲出了:“不同值的个数” > “子数组长度” ? “子数组长度” : “不同值的个数”。 8 | 9 | */ 10 | 11 | class Solution { 12 | public int distributeCandies(int[] candies) { 13 | Set nums = new HashSet<>(); 14 | for (int candy : candies) { 15 | nums.add(candy); 16 | } 17 | int numNums = nums.size(); 18 | int numTarget = candies.length / 2; 19 | return numNums >= numTarget ? numTarget : numNums; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /575. Distribute Candies/575. Distribute Candies.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 思路 3 | 这题换一个表达方式就是:一个数组,划分为元素个数相等的两份,使得其中一份中元素的值尽可能不相同。 4 | 5 | 这里一个关键点在于“不同值的个数”和“子数组长度”的关系。例如[1, 2, 3, 4]的“不同值的个数”是4,“子数组长度”是2,很显然无论如何划分都是最优解(如[1, 2]),即2;再例如[1, 1, 2, 2, 2, 2]的“不同值的个数”是2,“子数组长度”是3,最优的划分是[1, 1, 2]或[1, 2, 2],即2。 6 | 7 | 这样答案就呼之欲出了:“不同值的个数” > “子数组长度” ? “子数组长度” : “不同值的个数”。 8 | ''' 9 | 10 | class Solution: 11 | def distributeCandies(self, candies): 12 | """ 13 | :type candies: List[int] 14 | :rtype: int 15 | """ 16 | nums = set(candies) 17 | num_nums = len(nums) 18 | target_num = len(candies) // 2 19 | return target_num if num_nums >= target_num else num_nums 20 | -------------------------------------------------------------------------------- /575. Distribute Candies/Readme.md: -------------------------------------------------------------------------------- 1 | Given an integer array with even length, where different numbers in this array represent different kinds of candies. 2 | 3 | Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. 4 | 5 | Return the maximum number of kinds of candies the sister could gain. 6 | 7 | `Example 1:` 8 | 9 | Input: candies = [1,1,2,2,3,3] 10 | 11 | Output: 3 12 | 13 | Explanation: 14 | 15 | There are three different kinds of candies (1, 2 and 3), and two candies for each kind. 16 | 17 | Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. 18 | 19 | The sister has three different kinds of candies. 20 | 21 | Example 2: 22 | 23 | Input: candies = [1,1,2,3] 24 | 25 | Output: 2 26 | 27 | Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. 28 | 29 | The sister has two different kinds of candies, the brother has only one kind of candies. 30 | 31 | Note: 32 | 33 | The length of the given array is in range [2, 10,000], and will be even. 34 | 35 | The number in given array is in range [-100,000, 100,000]. 36 | -------------------------------------------------------------------------------- /621.Task Scheduler/621.Task Scheduler.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int leastInterval(vector& tasks, int n) { 4 | // frame size 5 | vector mVec(26,0); 6 | 7 | for(auto &val:tasks) { 8 | mVec[val-'A']++; 9 | } 10 | sort(mVec.begin(),mVec.end()); 11 | int i = 25; 12 | while(i>=0&&mVec[25]==mVec[i])i--; 13 | return max((mVec[25]-1)*(n+1)+25-i,static_cast(tasks.size())); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /645. Set Mismatch/645. Set Mismatch.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 最直接的一种解法就是统计每个数字出现的次数了,然后再遍历次数数组,如果某个数字出现了两次就是重复数,如果出现了0次,就是缺失数 3 | 4 | class Solution { 5 | public: 6 | vector findErrorNums(vector& nums) { 7 | vector res(2, 0), cnt(nums.size(), 0); 8 | for (int num : nums) ++cnt[num - 1]; 9 | for (int i = 0; i < cnt.size(); ++i) { 10 | if (res[0] != 0 && res[1] != 0) return res; 11 | if (cnt[i] == 2) res[0] = i + 1; 12 | else if (cnt[i] == 0) res[1] = i + 1; 13 | } 14 | return res; 15 | } 16 | }; 17 | 18 | 19 | /* 20 | 再来看一种更省空间的解法,这种解法思路相当巧妙,遍历每个数字,然后将其应该出现的位置上的数字变为其相反数, 21 | 这样如果我们再变为其相反数之前已经成负数了,说明该数字是重复数, 22 | 将其将入结果res中,然后再遍历原数组,如果某个位置上的数字为正数,说明该位置对应的数字没有出现过,加入res中即可 23 | 24 | */ 25 | 26 | class Solution { 27 | public: 28 | vector findErrorNums(vector& nums) { 29 | vector res(2, -1); 30 | for (int i : nums) { 31 | if (nums[abs(i) - 1] < 0) res[0] = abs(i); 32 | else nums[abs(i) - 1] *= -1; 33 | } 34 | for (int i = 0; i < nums.size(); ++i) { 35 | if (nums[i] > 0) res[1] = i + 1; 36 | } 37 | return res; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /645. Set Mismatch/645. Set Mismatch.java: -------------------------------------------------------------------------------- 1 | /* 2 | 题意大致如下:set S的长度为n,无序存储了数字1-n,但由于data error,有一个数字出现了重复(同时意味着有一个数字缺失),找出重复数字和缺失的数字。 3 | 用一个map,第一遍循环,把set S过一遍,出现的数字用map标记,同时记录下重复的数字(已标记过的数字第二次读到为重复数字)。 4 | 第二遍循环,把map过一遍,查找缺失数字(没有被标记的数字)。 5 | 时间复杂度为o(n)。 6 | 7 | */ 8 | 9 | public class Solution { 10 | public int[] findErrorNums(int[] nums) { 11 | int res[]=new int[2]; 12 | //boolean类型默认初始化为false 13 | boolean map[]=new boolean[nums.length+1]; 14 | for(int i=0;i i): 13 | p[i] = min(mx-i, p[2*id-i]) 14 | while i+p[i]+1 < n and i-p[i]-1 >=0 and s[i+p[i]+1] == s[i-p[i]-1]: 15 | p[i] += 1 16 | if(i + p[i] > mx): 17 | id = i 18 | mx = i + p[i] 19 | res += (p[i]+1)/2 20 | return res -------------------------------------------------------------------------------- /682. Baseball Game/682. Baseball Game.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int calPoints(vector &ops) { 4 | vector history; 5 | for (auto &op : ops) { 6 | if (op == "+") { 7 | history.push_back(history.back() + history[history.size() - 2]); 8 | } else if (op == "D") { 9 | 10 | history.push_back(history.back() * 2); 11 | } else if (op == "C") { 12 | history.pop_back(); 13 | } else { 14 | history.push_back(stoi(op)); 15 | } 16 | } 17 | return accumulate(history.begin(), history.end(), 0); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /682. Baseball Game/682. Baseball Game.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int calPoints(String[] ops) { 3 | Stack history = new Stack<>(); 4 | for (String op : ops) { 5 | switch (op) { 6 | case "+": 7 | history.push(history.peek() + history.get(history.size() - 2)); 8 | break; 9 | case "D": 10 | history.push(history.peek() * 2); 11 | break; 12 | case "C": 13 | history.pop(); 14 | break; 15 | default: 16 | history.push(Integer.parseInt(op)); 17 | } 18 | } 19 | int result = 0; 20 | for (int item : history) { 21 | result += item; 22 | } 23 | return result; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /682. Baseball Game/682. Baseball Game.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 如果只有Integer、+和D的话这题就非常简单了,只用保存上两轮的得分,以及一个累加和就好了。但注意到这里有C可以撤销上一轮的得分, 3 | 并且C出现的次数没有限制,那么这里就必须用到栈来记录和管理之前每轮的得分了。 4 | 5 | 那么这题实际上就是对栈的操作了: 6 | 7 | Integer:本轮得分为Integer,入栈。 8 | +:本轮得分为当前两个栈顶值之和,入栈。 9 | D:本轮得分为当前栈顶值的两倍,入栈。 10 | C:栈顶出栈。 11 | 最终结果为当前栈中所有值的和。 12 | ''' 13 | 14 | class Solution: 15 | def calPoints(self, ops): 16 | """ 17 | :type ops: List[str] 18 | :rtype: int 19 | """ 20 | history = [] 21 | for op in ops: 22 | if op == '+': 23 | history.append(history[-1] + history[-2]) 24 | elif op == 'D': 25 | history.append(history[-1] * 2) 26 | elif op == 'C': 27 | history.pop() 28 | else: 29 | history.append(int(op)) 30 | return sum(history) 31 | -------------------------------------------------------------------------------- /682. Baseball Game/Baseball Game by Andy.md: -------------------------------------------------------------------------------- 1 | [!image](https://github.com/hanlaoshi/leetcode-DailyProblem/blob/master/img-storage/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20190115223824.jpg) 2 | -------------------------------------------------------------------------------- /730. Count Different Palindromic Subsequences/730. Count Different Palindromic Subsequences.py: -------------------------------------------------------------------------------- 1 | 花花酱 : http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-730-count-different-palindromic-subsequences/ 2 | 3 | class Solution: 4 | def countPalindromicSubsequences(self, S): 5 | """ 6 | :type S: str 7 | :rtype: int 8 | """ 9 | def count(S, i, j): 10 | if i > j: return 0 11 | if i == j: return 1 12 | if self.m_[i][j]: 13 | return self.m_[i][j] 14 | if S[i] == S[j]: 15 | ans = count(S, i + 1, j - 1) * 2 16 | l = i + 1 17 | r = j - 1 18 | while l <= r and S[l] != S[i]: l += 1 19 | while l <= r and S[r] != S[i]: r -= 1 20 | if l > r: ans += 2 21 | elif l == r: ans += 1 22 | else: ans -= count(S, l + 1, r - 1) 23 | else: 24 | ans = count(S, i + 1, j) + count(S, i, j - 1) - count(S, i + 1, j - 1) 25 | 26 | self.m_[i][j] = ans % (10 ** 9 + 7) 27 | return self.m_[i][j] 28 | 29 | n = len(S) 30 | self.m_ = [[None for _ in range(n)] for _ in range(n)] 31 | return count(S, 0, n - 1) 32 | -------------------------------------------------------------------------------- /933.Number of Recent Calls/933.Number of Recent Calls.cpp: -------------------------------------------------------------------------------- 1 | class RecentCounter { 2 | public: 3 | vector times; 4 | 5 | RecentCounter() { 6 | 7 | } 8 | 9 | int find_start(int x){ 10 | int l = 0,r = times.size()-1; 11 | while(l < r){ 12 | int mid = (l + r) / 2; 13 | if(times[mid] >= x) r = mid; 14 | else l = mid + 1; 15 | } 16 | return l; 17 | } 18 | 19 | int ping(int t) { 20 | times.push_back(t); 21 | if(t <= 3000) return times.size(); 22 | int idx = find_start(t-3000); 23 | return times.size()-idx; 24 | } 25 | }; -------------------------------------------------------------------------------- /933.Number of Recent Calls/933.Number of Recent Calls.java: -------------------------------------------------------------------------------- 1 | //使用一个list来存储请求的时间,每一次调用ping函数,先把这次时间存入list中, 2 | //然后查找list中所有和当前时间差大于3000的项并删除。接着返回list的大小即可。 3 | //注:因为这里经常删除,所以用LinkedList的效率会更高一些(ArrayList会挪动元素)。并且删除要用iterator迭代器来删除,否则会引发ConcurrentModificationException。 4 | 5 | class RecentCounter { 6 | Listlist = new LinkedList(); 7 | 8 | public RecentCounter() { 9 | 10 | } 11 | 12 | public int ping(int t) { 13 | list.add(t); 14 | Iterator iterator = list.iterator(); 15 | while(iterator.hasNext()) 16 | { 17 | Integer a = iterator.next(); 18 | if(t-a > 3000) 19 | iterator.remove(); 20 | else break; 21 | } 22 | return list.size(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /933.Number of Recent Calls/933.Number of Recent Calls.py: -------------------------------------------------------------------------------- 1 | #------------deque实现。------------------- 2 | from collections import deque 3 | class RecentCounter: 4 | def __init__(self): 5 | self.pings = deque() 6 | 7 | def ping(self, t): 8 | """ 9 | :type t: int 10 | :rtype: int 11 | """ 12 | self.pings.append(t) 13 | while self.pings[0] < t - 3000: 14 | self.pings.popleft() 15 | return len(self.pings) 16 | 17 | 18 | #-------------二分搜索发优化搜索过程------------------------ 19 | class RecentCounter: 20 | def __init__(self): 21 | self.pings = list() 22 | 23 | def ping(self, t): 24 | """ 25 | :type t: int 26 | :rtype: int 27 | """ 28 | self.pings.append(t) 29 | l, r = 0, len(self.pings) 30 | if t > 3000: 31 | while l < r: 32 | mid = (l + r)//2 33 | if self.pings[mid] < t - 3000: 34 | l = mid + 1 35 | else: 36 | r = mid 37 | 38 | return len(self.pings) - l 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # leetcode--DailyProblem 2 | 1. 为了方便大家学习交流并且统一管理题目,特意建立此repo; 3 | 4 | 2. 每题的解题方法包括但不限于c++, java, python,欢迎大家补充; 5 | 6 | 3. 公众号为: AI数据分析算法 ,欢迎大家关注、交流。 7 | 8 | 4. 欢迎扫码加入我们的公众号,日常打卡,期待大家一起变优秀,成为offer收割机!!! 9 | 10 | ![gongzhonghao](https://github.com/hanlaoshi/leetcode-One-topic-per-day/blob/master/img-storage/gongzhonghao.jpg?raw=true) 11 | 12 | 5. [我的博客](https://blog.csdn.net/hanjushi2) 13 | -------------------------------------------------------------------------------- /img-storage/027.Remove Element.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/027.Remove Element.jpg -------------------------------------------------------------------------------- /img-storage/028.Implement strStr().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/028.Implement strStr().png -------------------------------------------------------------------------------- /img-storage/035.Search Insert Position.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/035.Search Insert Position.jpg -------------------------------------------------------------------------------- /img-storage/2018-10-31_181616.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/2018-10-31_181616.png -------------------------------------------------------------------------------- /img-storage/225. Implement Stack using Queues.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/225. Implement Stack using Queues.png -------------------------------------------------------------------------------- /img-storage/26.RemoveDuplicates fromSorted Array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/26.RemoveDuplicates fromSorted Array.png -------------------------------------------------------------------------------- /img-storage/682baseball_game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/682baseball_game.png -------------------------------------------------------------------------------- /img-storage/75.leetcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/75.leetcode.png -------------------------------------------------------------------------------- /img-storage/94.stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/94.stack.png -------------------------------------------------------------------------------- /img-storage/96.tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/96.tree.png -------------------------------------------------------------------------------- /img-storage/Container With Most Water.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/Container With Most Water.jpg -------------------------------------------------------------------------------- /img-storage/Implement Queue using Stacks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/Implement Queue using Stacks.png -------------------------------------------------------------------------------- /img-storage/Longest Common Prefix.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/Longest Common Prefix.jpg -------------------------------------------------------------------------------- /img-storage/Roman_to_int - 副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/Roman_to_int - 副本.png -------------------------------------------------------------------------------- /img-storage/Roman_to_int.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/Roman_to_int.png -------------------------------------------------------------------------------- /img-storage/Unique_Paths.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/Unique_Paths.png -------------------------------------------------------------------------------- /img-storage/add_two_nums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/add_two_nums.png -------------------------------------------------------------------------------- /img-storage/gongzhonghao.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/gongzhonghao.jpg -------------------------------------------------------------------------------- /img-storage/readme.md: -------------------------------------------------------------------------------- 1 | 封面图片 2 | -------------------------------------------------------------------------------- /img-storage/微信图片_20190115223824.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanlaoshi/leetcode-DailyProblem/88a545bc5d54d0cbe7a60f15ffe5c5da151f6277/img-storage/微信图片_20190115223824.jpg -------------------------------------------------------------------------------- /面试题/1/readme.md: -------------------------------------------------------------------------------- 1 | 1. 一个有序数组,拆成两部分a b,然后现在按b a的顺序把该数组给你, 2 | 然后让你在该数组中查找某个数。eg 1 2 3 4 5有序,但是给你3 4 5 1 2 3 | 4 | 33.leetcode -------------------------------------------------------------------------------- /面试题/2/readme.md: -------------------------------------------------------------------------------- 1 | 2. 二维数组,每一行从左到右递增,每一列从上到下递增,现要你找出一个数是否存在在该数组中 2 | 240.leetcode -------------------------------------------------------------------------------- /面试题/3/baidu.txt: -------------------------------------------------------------------------------- 1 | 感谢 @ 多年未见 提供 2 | 3 | 百度面试题,有一个数组,先严格升序,后严格降序,eg 1 3 5 4 2,找出最大的数 4 | 5 | 可以参考leet 852题 6 | 7 | class Solution { 8 | public: 9 | int peakIndexInMountainArray(vector& A) { 10 | int l = 0, r = A.size() - 1; 11 | while (l <= r) { 12 | int mid = (l + r) >> 1; 13 | if (A[mid] > A[mid - 1] && A[mid] > A[mid + 1]) return mid; 14 | else if (A[mid] > A[mid - 1] && A[mid] < A[mid + 1]) l = mid + 1; 15 | else r = mid - 1; 16 | } 17 | return -1; 18 | } 19 | }; 20 | --------------------------------------------------------------------------------