Day1:
爬楼梯:leetcode-70
https://leetcode-cn.com/problems/climbing-stairs/
Day2:
加一:leetcode-66
https://leetcode-cn.com/problems/plus-one/
Day3:
两数之和:leetcode-1
https://leetcode-cn.com/problems/two-sum/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ
Day4:
两两交换链表中的节点:leetcode-24
https://leetcode-cn.com/problems/swap-nodes-in-pairs/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ
Day5
合并两个有序链表:leetcode-21
https://leetcode-cn.com/problems/merge-two-sorted-lists/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null){
return l2;
}else if(l2 == null){
return l1;
}else if(l1.val < l2.val){
l1.next = mergeTwoLists(l1.next,l2);
return l1;
}else{
l2.next = mergeTwoLists(l1,l2.next);
return l2;
}
}
}
Day6
猜数字游戏
https://leetcode-cn.com/problems/bulls-and-cows/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ
public String getHint(String secret, String guess) {
int A = 0;
for (int i = 0; i < guess.length(); i++) {
if (secret.charAt(i) == guess.charAt(i)) {
A++;
}
}
HashMap<Character, Integer> mapS = new HashMap<>();
HashMap<Character, Integer> mapG = new HashMap<>();
for (int i = 0; i < secret.length(); i++) {
mapS.put(secret.charAt(i), mapS.getOrDefault(secret.charAt(i), 0) + 1);
mapG.put(guess.charAt(i), mapG.getOrDefault(guess.charAt(i), 0) + 1);
}
int B = 0;
for (Character key : mapG.keySet()) {
int n1 = mapG.getOrDefault(key, 0);
int n2 = mapS.getOrDefault(key, 0);
B = B + Math.min(n1, n2);
}
return A + "A" + (B - A) + "B";
}
Day7:
设计循环双端队列: https://leetcode-cn.com/problems/design-circular-deque/
class MyCircularDeque {
private int capacity;
private int[] arr;
private int front;
private int rear;
/** Initialize your data structure here. Set the size of the deque to be k. */
public MyCircularDeque(int k) {
capacity = k + 1;
arr = new int[capacity];
front = 0;
rear = 0;
}
/** Adds an item at the front of Deque. Return true if the operation is successful. */
public boolean insertFront(int value) {
if(isFull()) return false;
front = (front - 1 +capacity)%capacity;
arr[front] = value;
return true;
}
/** Adds an item at the rear of Deque. Return true if the operation is successful. */
public boolean insertLast(int value) {
if(isFull()) return false;
arr[rear] = value;
rear = (rear+1)%capacity;
return true;
}
/** Deletes an item from the front of Deque. Return true if the operation is successful. */
public boolean deleteFront() {
if(isEmpty()) return false;
front = (front + 1)%capacity;
return true;
}
/** Deletes an item from the rear of Deque. Return true if the operation is successful. */
public boolean deleteLast() {
if(isEmpty()) return false;
rear = (rear - 1 + capacity)%capacity;
return true;
}
/** Get the front item from the deque. */
public int getFront() {
if(isEmpty()) return -1;
return arr[front];
}
/** Get the last item from the deque. */
public int getRear() {
if(isEmpty()) return -1;
return arr[(rear-1+capacity)%capacity];
}
/** Checks whether the circular deque is empty or not. */
public boolean isEmpty() {
return front == rear;
}
/** Checks whether the circular deque is full or not. */
public boolean isFull() {
return (rear+1)%capacity == front;
}
}
/**
* Your MyCircularDeque object will be instantiated and called as such:
* MyCircularDeque obj = new MyCircularDeque(k);
* boolean param_1 = obj.insertFront(value);
* boolean param_2 = obj.insertLast(value);
* boolean param_3 = obj.deleteFront();
* boolean param_4 = obj.deleteLast();
* int param_5 = obj.getFront();
* int param_6 = obj.getRear();
* boolean param_7 = obj.isEmpty();
* boolean param_8 = obj.isFull();
*/
Day8
两个数组的交集 II
https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ
public int[] intersect(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return intersect(nums2, nums1);
}
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : nums1) {
int count = map.getOrDefault(num, 0) + 1;
map.put(num, count);
}
int[] intersection = new int[nums1.length];
int index = 0;
for (int num : nums2) {
int count = map.getOrDefault(num, 0);
if (count > 0) {
intersection[index++] = num;
count--;
if (count > 0) {
map.put(num, count);
} else {
map.remove(num);
}
}
}
return Arrays.copyOfRange(intersection, 0, index);
}
@所有人
每日一题推荐:
♥️【Day9】
删除最外层的括号:
https://leetcode-cn.com/problems/remove-outermost-parentheses/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ
public String getParentString(String S){
StringBuilder sb = new StringBuilder();
int level = 0;
for (Character c:S.toCharArray()){
if (c == ')') --level;
if (level>=1) sb.append(c);
if (c == '(') ++level;
}
return sb.toString();
}
@所有人
每日一题推荐:
♥️【Day10】
滑动窗口的最大值
https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
if (n * k == 0) return new int[0];
int [] output = new int[n - k + 1];
for (int i = 0; i < n - k + 1; i++) {
int max = Integer.MIN_VALUE;
for(int j = i; j < i + k; j++)
max = Math.max(max, nums[j]);
output[i] = max;
}
return output;
}
【Day13】
https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
int left_Depth = maxDepth(root.left);
int right_Depth = maxDepth(root.right);
return (left_Depth > right_Depth ? left_Depth:right_Depth)+1;
}
}
【Day14】
void moveZeroes(int* nums, int numsSize){
int i, k;
int j = 0;
for(i = 0;i< numsSize;i++){
if(nums[i] != 0){
nums[i] = k;
nums[j] = nums[i];
k = nums[j];
j++;
}
}
}
【Day15】
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> res = new ArrayList<Integer>();
helper(root,res);
return res;
}
public void helper(TreeNode root,ArrayList<Integer> res){
if(root != null){
if(root.left != null){
helper(root.left,res);
}
res.add(root.val);
if(root.right != null){
helper(root.right,res);
}
}
}
@所有人
♥️每日一题推荐
【Day16】
剑指 Offer 05. 替换空格
https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/
public String replaceSpace(String s) {
s = s.replaceAll(" ","%20");
return s;
}
@所有人
♥️每日一题推荐
【Day17】每日一题推荐
从尾到头打印链表
https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof
//从头到尾反过来返回每个节点的值
public int[] reversePrint(ListNode head) {
Stack<Integer> stack = new Stack<>();
int n = 0;
while (head !=null){
stack.push(head.val);
n++;
head = head.next;
}
int[] res = new int[n];
int i = 0;
while (!stack.isEmpty()){
res[i++] = stack.peek();
stack.pop();
}
return res;
}
@所有人
♥️每日一题推荐
【Day18】
面试题68 - II. 二叉树的最近公共祖先 https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/
递归解析:
终止条件:
当越过叶节点,则直接返回 nullnull ;
当 rootroot 等于 p, qp,q ,则直接返回 rootroot ;
递推工作:
开启递归左子节点,返回值记为 leftleft ;
开启递归右子节点,返回值记为 rightright ;
返回值: 根据 leftleft 和 rightright ,可展开为四种情况;
当 leftleft 和 rightright 同时为空 :说明 rootroot 的左 / 右子树中都不包含 p,qp,q ,返回 nullnull ;
当 leftleft 和 rightright 同时不为空 :说明 p, qp,q 分列在 rootroot 的 异侧 (分别在 左 / 右子树),因此 rootroot 为最近公共祖先,返回 rootroot ;
当 leftleft 为空 ,rightright 不为空 :p,qp,q 都不在 rootroot 的左子树中,直接返回 rightright 。具体可分为两种情况:
p,qp,q 其中一个在 rootroot 的 右子树 中,此时 rightright 指向 pp(假设为 pp );
p,qp,q 两节点都在 rootroot 的 右子树 中,此时的 rightright 指向 最近公共祖先节点 ;
当 leftleft 不为空 , rightright 为空 :与情况 3. 同理;
//二叉树的最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if (left == null && right == null) return null;
if (left == null) return right;
if (right == null) return left;
return root;
}
【Day19】18. 四数之和(https://leetcode-cn.com/problems/4sum/)
https://leetcode-cn.com/problems/4sum/
四数之和与前面三数之和的思路几乎是一样的,嗝。(刚好前些天才写了三数之和的题解)
如果前面的三数之和会做了的话,这里其实就是在前面的基础上多添加一个遍历的指针而已。
会做三数之和的可以不用看下面的了。。
使用四个指针(a<b<c<d)。固定最小的a和b在左边,c=b+1,d=_size-1 移动两个指针包夹求解。
保存使得nums[a]+nums[b]+nums[c]+nums[d]==target的解。偏大时d左移,偏小时c右移。c和d相
遇时,表示以当前的a和b为最小值的解已经全部求得。b++,进入下一轮循环b循环,当b循环结束后。
a++,进入下一轮a循环。 即(a在最外层循环,里面嵌套b循环,再嵌套双指针c,d包夹求解)。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
vector<std::vector<int> > res;
if (nums.size()<4) {
return res;
}
int a,b,c,d,_size = nums.size();
for (a = 0; a<=_size-4; a++) {
if (a>0 && nums[a] == nums[a-1]) continue;
for (b=a+1; b<=_size-3; b++) {
if (b>a+1 && nums[b] == nums[b-1]) continue;
c=b+1,d=_size-1;
while (c<d) {
if (nums[a] + nums[b] + nums[c] + nums[d] < target) c++;
else if (nums[a]+nums[b]+nums[c]+nums[d] > target) d--;
else{
res.push_back({nums[a],nums[b],nums[c],nums[d]});
while (c<d && nums[c+1] == nums[c]) c++;
while (c<d && nums[d-1] == nums[d]) d--;
c++;
d--;
}
}
}
}
return res;
}
};
【Day20】三数之和(8月29日)
https://leetcode-cn.com/problems/3sum/
方法一:排序 + 双指针
题目中要求找到所有「不重复」且和为 00 的三元组,这个「不重复」的要求使得我们无法简单地使用三重循环枚举所有的三元组。这是因为在最坏的情况下,数组中的元素全部为 00,即
[0, 0, 0, 0, 0, ..., 0, 0, 0]
任意一个三元组的和都为 00。如果我们直接使用三重循环枚举三元组,会得到 O(N^3)O(N
3
) 个满足题目要求的三元组(其中 NN 是数组的长度)时间复杂度至少为 O(N^3)O(N
3
)。在这之后,我们还需要使用哈希表进行去重操作,得到不包含重复三元组的最终答案,又消耗了大量的空间。这个做法的时间复杂度和空间复杂度都很高,因此我们要换一种思路来考虑这个问题。
「不重复」的本质是什么?我们保持三重循环的大框架不变,只需要保证:
第二重循环枚举到的元素不小于当前第一重循环枚举到的元素;
第三重循环枚举到的元素不小于当前第二重循环枚举到的元素。
也就是说,我们枚举的三元组 (a, b, c)(a,b,c) 满足 a \leq b \leq ca≤b≤c,保证了只有 (a, b, c)(a,b,c) 这个顺序会被枚举到,而 (b, a, c)(b,a,c)、(c, b, a)(c,b,a) 等等这些不会,这样就减少了重复。要实现这一点,我们可以将数组中的元素从小到大进行排序,随后使用普通的三重循环就可以满足上面的要求。
同时,对于每一重循环而言,相邻两次枚举的元素不能相同,否则也会造成重复。举个例子,如果排完序的数组为
[0, 1, 2, 2, 2, 3]
^ ^ ^
我们使用三重循环枚举到的第一个三元组为 (0, 1, 2)(0,1,2),如果第三重循环继续枚举下一个元素,那么仍然是三元组 (0, 1, 2)(0,1,2),产生了重复。因此我们需要将第三重循环「跳到」下一个不相同的元素,即数组中的最后一个元素 33,枚举三元组 (0, 1, 3)(0,1,3)。
下面给出了改进的方法的伪代码实现:
nums.sort()
for first = 0 .. n-1
// 只有和上一次枚举的元素不相同,我们才会进行枚举
if first == 0 or nums[first] != nums[first-1] then
for second = first+1 .. n-1
if second == first+1 or nums[second] != nums[second-1] then
for third = second+1 .. n-1
if third == second+1 or nums[third] != nums[third-1] then
// 判断是否有 a+b+c==0
check(first, second, third)
这种方法的时间复杂度仍然为 O(N^3)O(N
3
),毕竟我们还是没有跳出三重循环的大框架。然而它是很容易继续优化的,可以发现,如果我们固定了前两重循环枚举到的元素 aa 和 bb,那么只有唯一的 cc 满足 a+b+c=0a+b+c=0。当第二重循环往后枚举一个元素 b'b
′
时,由于 b' > bb
′
b,那么满足 a+b'+c'=0a+b
′
+c
′
=0 的 c'c
′
一定有 c' < cc
′
<c,即 c'c
′
在数组中一定出现在 cc 的左侧。也就是说,我们可以从小到大枚举 bb,同时从大到小枚举 cc,即第二重循环和第三重循环实际上是并列的关系。
有了这样的发现,我们就可以保持第二重循环不变,而将第三重循环变成一个从数组最右端开始向左移动的指针,从而得到下面的伪代码:
nums.sort()
for first = 0 .. n-1
if first == 0 or nums[first] != nums[first-1] then
// 第三重循环对应的指针
third = n-1
for second = first+1 .. n-1
if second == first+1 or nums[second] != nums[second-1] then
// 向左移动指针,直到 a+b+c 不大于 0
while nums[first]+nums[second]+nums[third] > 0
third = third-1
// 判断是否有 a+b+c==0
check(first, second, third)
这个方法就是我们常说的「双指针」,当我们需要枚举数组中的两个元素时,如果我们发现随着第一个元素的递增,第二个元素是递减的,那么就可以使用双指针的方法,将枚举的时间复杂度从 O(N^2)O(N
2
) 减少至 O(N)O(N)。为什么是 O(N)O(N) 呢?这是因为在枚举的过程每一步中,「左指针」会向右移动一个位置(也就是题目中的 bb),而「右指针」会向左移动若干个位置,这个与数组的元素有关,但我们知道它一共会移动的位置数为 O(N)O(N),均摊下来,每次也向左移动一个位置,因此时间复杂度为 O(N)O(N)。
注意到我们的伪代码中还有第一重循环,时间复杂度为 O(N)O(N),因此枚举的总时间复杂度为 O(N^2)O(N
2
)。由于排序的时间复杂度为 O(N \log N)O(NlogN),在渐进意义下小于前者,因此算法的总时间复杂度为 O(N^2)O(N
2
)。
上述的伪代码中还有一些细节需要补充,例如我们需要保持左指针一直在右指针的左侧(即满足 b \leq cb≤c),具体可以参考下面的代码,均给出了详细的注释。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
List<List<Integer>> ans = new ArrayList<List<Integer>>();
for (int first = 0;first<n;++first){
//需要和上一次枚举的数不相同
if (first>0 && nums[first] == nums[first-1]){
continue;
}
//c对应的指针初始指向数组的最右端
int third = n -1;
int target = -nums[first];
//枚举b
for (int second = first + 1;second<n;++second){
//需要和上一次枚举的数不相同
if (second>first+1&&nums[second] == nums[second-1]){
continue;
}
//需要保证b的指针在c的指针的右侧
while (second < third && nums[second] + nums[third] > target){
--third;
}
//如果指针重合,随着b后续的增加
//就不会有满足a+b+c=0并且b<c的c了,可以退出循环
if(second == third){
break;
}
if (nums[second] + nums[third] == target){
List<Integer> list = new ArrayList<Integer>();
list.add(nums[first]);
list.add(nums[second]);
list.add(nums[third]);
ans.add(list);
}
}
}
return ans;
}
}
【Day21】面试题 17.09. 第 k 个数 (8月30日)
https://leetcode-cn.com/problems/get-kth-magic-number-lcci/
/*
* 核心思想:下一个数值,总是由上一个数值*3或5或7得到的,因此考虑三个数列:
* 1、dp[0]*3,dp[1]*3,dp[2]*3,...
* 2、dp[0]*5,dp[1]*5,dp[2]*5,...
* 3、dp[0]*7,dp[1]*7,dp[2]*7,...
* 将上面按照从小到大,合并到一起即可,如何做到这点,则需要设置三个指针,每个指针指向那种类型的最小值即可.
* 初始状态:p3=0, p5=0, p7=0
* dp[1] = Min(dp[p3]*3, dp[p5]*5, dp[p7]*7)
* Min(1*3, 1*5, 1*7)
* dp[1] = 3
* 因此p3后移,即p3++,p3=1
* dp[2] = Min(dp[p3]*3, dp[p5]*5, dp[7]*7)
* Min(3*3, 1*5, 1*7)
* dp[2] = 5
* 因此p5后移,p5++,p5=1
* dp[3] = Min(dp[p3]*3, dp[p5]*5, dp[p7]*7)
* Min(3*3, 3*5, 1*7)
* dp[3]=7
* 因此p7后移,即p7++,p7=1
* */
三指针+动态规划
class Solution {
public int getKthMagicNumber(int k) {
int dp[] = new int[k];
int p3 = 0,p5=0,p7=0;
dp[0] = 1;
for (int i =1;i<k;i++){
dp[i] = Math.min(Math.min(dp[p3]*3,dp[p5] * 5),dp[p7] * 7);//找到最小值
//如果当前值与某类指针指向的值相同,则后移指针【每轮三个if判断必须都执行,防止排列组合之后是重复的值】
if (dp[i] == dp[p3] * 3) p3++;
if (dp[i] == dp[p5] * 5) p5++;
if (dp[i] == dp[p7] * 7) p7++;
}
return dp[k-1];
}
}
【Day22】46. 全排列 (8月31日)
https://leetcode-cn.com/problems/permutations/
class Solution {
public List<List<Integer>> permute(int[] nums) {
int len = nums.length;
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(len == 0)return res;
ArrayList<Integer> path = new ArrayList<Integer>();
boolean[] used = new boolean[len];
dfs(nums,len,0,path,used,res);
return res;
}
public void dfs(int[] nums,Integer len,Integer depth,List<Integer>path,boolean[] used,List<List<Integer>> res){
if(depth == len){
res.add(new ArrayList(path));
return;
}
for(int i = 0; i< len;i++){
if(!used[i]){
path.add(nums[i]);
used[i] = true;
dfs(nums,len,depth + 1,path,used,res);
used[i] = false;
path.remove(path.size() - 1);
}
}
}
}
【Day23】509. 斐波那契数 (9月1日)
https://leetcode-cn.com/problems/fibonacci-number/
class Solution {
public int fib(int N) {
if(N == 0 || N == 1) return N;
int m = N-1;
int n = N-2;
int sum = fib(m) + fib(n);
return sum;
}
}
O(2^n)
O(n)
class Solution {
public int fib(int N) {
if(N == 0 || N == 1) return N;
if(N==2) return 1;
int m = 1;
int n = 1;
int res = 0;
for(int i = 3;i<=N;i++){
res = m + n;
n = m;
m = res;
}
return res;
}
}
O(n)
O(1)
【Day24】122. 买卖股票的最佳时机 (9月2日)
II https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/description/
//贪心算法
class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
if(len < 2) return 0;
int res = 0;
for(int i = 1;i<len;i++){
int diff = prices[i] - prices[i-1];
if(diff > 0){
res += diff;
}
}
return res;
}
}
【Day25】860. 柠檬水找零 (9月3日)
https://leetcode-cn.com/problems/lemonade-change/description/
【Day26】200. 岛屿数量 (9月4日)
https://leetcode-cn.com/problems/number-of-islands/
【Day27】367. 有效的完全平方数 (9月5日)
https://leetcode-cn.com/problems/valid-perfect-square/
【Day28】169. 多数元素 (9月6日)
https://leetcode-cn.com/problems/majority-element/
【Day29】127. 单词接龙
https://leetcode-cn.com/problems/word-ladder/description/
【Day30】560. 和为K的子数组 (9月8日)
https://leetcode-cn.com/problems/subarray-sum-equals-k/
【Day31】874. 模拟行走机器人
https://leetcode-cn.com/problems/walking-robot-simulation/description/
【Day32】53. 最大子序和 (9月10日)
https://leetcode-cn.com/problems/maximum-subarray/
【Day33】1143. 最长公共子序列 (9月11日)
https://leetcode-cn.com/problems/longest-common-subsequence/
【Day34】74. 搜索二维矩阵
https://leetcode-cn.com/problems/search-a-2d-matrix/
【Day35】剑指 Offer 05. 替换空格
https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/
【Day36】64. 最小路径和 (9月14日)
https://leetcode-cn.com/problems/minimum-path-sum/
【Day37】322. 零钱兑换 (9.15)
https://leetcode-cn.com/problems/coin-change/
【Day38】213. 打家劫舍 II (9.16)
https://leetcode-cn.com/problems/house-robber-ii/description/
【Day39】
【Day40】363. 矩形区域不超过 K 的最大数值和 (9.18)
https://leetcode-cn.com/problems/max-sum-of-rectangle-no-larger-than-k/
【Day41】33. 搜索旋转排序数组 (9.19)
https://leetcode-cn.com/problems/search-in-rotated-sorted-array/
【Day42】212. 单词搜索 II
https://leetcode-cn.com/problems/word-search-ii/
【Day43】240. 搜索二维矩阵 II (9.21)
https://leetcode-cn.com/problems/search-a-2d-matrix-ii/
【Day44】208. 实现 Trie (前缀树) (9.22)
https://leetcode-cn.com/problems/implement-trie-prefix-tree/
【Day45】130. 被围绕的区域 https://leetcode-cn.com/problems/surrounded-regions/
【Day46】152. 乘积最大子数组 https://leetcode-cn.com/problems/maximum-product-subarray/
【Day47】126. 单词接龙 II https://leetcode-cn.com/problems/word-ladder-ii/
【Day48】16. 最接近的三数之和 https://leetcode-cn.com/problems/3sum-closest/
【Day49】22. 括号生成 https://leetcode-cn.com/problems/generate-parentheses/
【Day50】547. 朋友圈
https://leetcode-cn.com/problems/friend-circles/
【Day51】633. 平方数之和 https://leetcode-cn.com/problems/sum-of-square-numbers/
【Day52】198. 打家劫舍 https://leetcode-cn.com/problems/house-robber/
【Day56】718. 最长重复子数组 https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/
【Day57】387. 字符串中的第一个唯一字符 https://leetcode-cn.com/problems/first-unique-character-in-a-string/
【Day58】62. 不同路径 https://leetcode-cn.com/problems/unique-paths/
【Day59】541. 反转字符串 II https://leetcode-cn.com/problems/reverse-string-ii/
【Day60】300. 最长上升子序列 (10月8日)
https://leetcode-cn.com/problems/longest-increasing-subsequence/
【Day61】371. 两整数之和
https://leetcode-cn.com/problems/sum-of-two-integers/
【Day62】680. 验证回文字符串 Ⅱ https://leetcode-cn.com/problems/valid-palindrome-ii/
【Day63】32. 最长有效括号 (10月10日)
https://leetcode-cn.com/problems/longest-valid-parentheses/
【Day64】83. 删除排序链表中的重复元素
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/
【Day65】120. 三角形最小路径和
https://leetcode-cn.com/problems/triangle/
【Day69】238. 除自身以外数组的乘积
https://leetcode-cn.com/problems/product-of-array-except-self/
【Day70】76. 最小覆盖子串 https://leetcode-cn.com/problems/minimum-window-substring/
【Day71 】130. 被围绕的区域
https://leetcode-cn.com/problems/surrounded-regions/
【Day72 】1. 两数之和
https://leetcode-cn.com/problems/two-sum/
【Day73 】20. 有效的括号
https://leetcode-cn.com/problems/valid-parentheses/
【Day74】394. 字符串解码
https://leetcode-cn.com/problems/decode-string/
【Day75 】146. LRU缓存机制
https://leetcode-cn.com/problems/lru-cache/
【Day76】 208. 实现 Trie (前缀树)
https://leetcode-cn.com/problems/implement-trie-prefix-tree/
【Day77 】211. 添加与搜索单词 - 数据结构设计
https://leetcode-cn.com/problems/design-add-and-search-words-data-structure/
【Day78】 389. 找不同
https://leetcode-cn.com/problems/find-the-difference/
【Day79】 290. 单词规律
https://leetcode-cn.com/problems/word-pattern/
【Day80】387. 字符串中的第一个唯一字符
https://leetcode-cn.com/problems/first-unique-character-in-a-string/