From 96cd1ef54a2d5769ce102932d39b950751d738a8 Mon Sep 17 00:00:00 2001 From: fengt Date: Fri, 23 Oct 2020 17:18:38 +0800 Subject: [PATCH 01/14] week01 --- GrammerMD.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++ week01/NOTE.md | 19 ++++++++- week01/No1.java | 32 ++++++++++++++ week01/No21.java | 39 +++++++++++++++++ week01/No283.java | 0 week01/No66.java | 39 +++++++++++++++++ 6 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 GrammerMD.md create mode 100644 week01/No1.java create mode 100644 week01/No21.java create mode 100644 week01/No283.java create mode 100644 week01/No66.java diff --git a/GrammerMD.md b/GrammerMD.md new file mode 100644 index 00000000..df690329 --- /dev/null +++ b/GrammerMD.md @@ -0,0 +1,104 @@ + +一、标题 +在想要设置为标题的文字前面加#来表示 +一个#是一级标题,二个#是二级标题,以此类推。支持六级标题。 +# 这是一级标题 +## 这是二级标题 +### 这是三级标题 +#### 这是四级标题 +##### 这是五级标题 +###### 这是六级标题 + +二、字体 +加粗:要加粗的文字左右分别用两个*号包起来 +斜体:要倾斜的文字左右分别用一个*号包起来 +斜体加粗:要倾斜和加粗的文字左右分别用三个*号包起来 +删除线:要加删除线的文字左右分别用两个~~号包起来 + +示例: +**这是加粗的文字** +*这是倾斜的文字* +***这是斜体加粗的文字*** +~~这是加删除线的文字~~ + +三、引用 +在引用的文字前加>即可。引用也可以嵌套,如加两个>>三个>>> +>这是引用的内容 +>>这是引用的内容 +>>>>>>>>>>这是引用的内容 +--- +四、分割线 +三个或者三个以上的 - 或者 * 都可以。 +示例: +--- +---- +*** +***** +五、图片 +语法: +![图片alt](图片地址 ''图片title'') +图片alt就是显示在图片下面的文字,相当于对图片内容的解释。 +图片title是图片的标题,当鼠标移到图片上时显示的内容。title可加可不加 + +六、超链接 +语法:[超链接名](超链接地址 "超链接title") +title可加可不加 +示例: +[简书](http://jianshu.com) +[百度](http://baidu.com) + +七、列表 +无序列表 +语法:无序列表用 - + * 任何一种都可以 +- 列表内容 ++ 列表内容 +* 列表内容 +注意:- + * 跟内容之间都要有一个空格 +有序列表 +语法:数字加点 +1. 列表内容 +2. 列表内容 +3. 列表内容 +注意:序号跟内容之间要有空格 +上一级和下一级之间敲三个空格即可 + +八、表格 +语法: +表头|表头|表头 +---|:--:|---: +内容|内容|内容 +内容|内容|内容 + +第二行分割表头和内容。 +- 有一个就行,为了对齐,多加了几个 +文字默认居左 +-两边加:表示文字居中 +-右边加:表示文字居右 +注:原生的语法两边都要用 | 包起来。此处省略 + +示例: +姓名|技能|排行 +--|:--:|--: +刘备|哭|大哥 +关羽|打|二哥 +张飞|骂|三弟 + +九、代码 +语法: +单行代码:代码之间分别用一个反引号包起来 + `代码内容` +代码块:代码之间分别用三个反引号包起来,且两边的反引号单独占一行 +(```) + 代码... + 代码... + 代码... +(```) + +`create database hero;` +``` +function fun(){ + echo "这是一句非常牛逼的代码"; +} +fun(); +``` + diff --git a/week01/NOTE.md b/week01/NOTE.md index 50de3041..3e7d29ee 100644 --- a/week01/NOTE.md +++ b/week01/NOTE.md @@ -1 +1,18 @@ -学习笔记 \ No newline at end of file +#学习总结 + + ##切题四件套: + 1. clarification 看清题,理解透彻 + 2. possible solutions 所有解题思路过一遍,再动手比较、找最优化 + 3. coding 多写 + 4. test cases 想测试案例 + ## “五毒神掌”:五遍刷题;练习缺陷、弱点地方。 + - 第一遍:读题,思考,10分钟没有思路直接看答案 + - 第二遍:自己写,去LeetCode提交(不看答案),知道提交通过 + - 第三遍:过了一天后再重新做题 + - 第四遍:过了一周后再重复做题 + - 第五遍:面试前看题目(个人理解为定期复习) + ** 看LeetCode 国际版,题解靠前的 ** + ## 个人理解 + - 基本数据结构与题目结合有特定的场景,一定要把题目多读几遍 + - 实践下来,有些题目第一遍做不出来,看了答案后还是看不懂,这种需要花费很多实践去搞懂,真的懂了,类似的问题就一通百通了 + diff --git a/week01/No1.java b/week01/No1.java new file mode 100644 index 00000000..f17a305d --- /dev/null +++ b/week01/No1.java @@ -0,0 +1,32 @@ +//给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 +// +// 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 +// +// 示例: +// +// 给定 nums = [2, 7, 11, 15], target = 9 +// +//因为 nums[0] + nums[1] = 2 + 7 = 9 +//所以返回 [0, 1] +// +// Related Topics 数组 哈希表 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + + public int[] twoSum(int[] nums, int target) { + Map map = new HashMap<>(); + for(int i=0;i2->4, 1->3->4 +//输出:1->1->2->3->4->4 +// +// Related Topics 链表 +// 👍 1340 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +/** + * 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; + if(l2==null) return l1; + //如果l1小,就再去比较l1后的那个数 + if(l1.val Date: Fri, 23 Oct 2020 17:22:39 +0800 Subject: [PATCH 02/14] Update NOTE.md --- week01/NOTE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/week01/NOTE.md b/week01/NOTE.md index 3e7d29ee..4a2a3ca5 100644 --- a/week01/NOTE.md +++ b/week01/NOTE.md @@ -1,6 +1,6 @@ #学习总结 - ##切题四件套: + ## 切题四件套: 1. clarification 看清题,理解透彻 2. possible solutions 所有解题思路过一遍,再动手比较、找最优化 3. coding 多写 From 9d84a3906e22232e5e9ce733e57a1b522481de1f Mon Sep 17 00:00:00 2001 From: fengt Date: Thu, 29 Oct 2020 14:45:27 +0800 Subject: [PATCH 03/14] week02 --- week02/NOTE.md | 32 ++++++++++++++++++++++++++++- week02/No1.java | 52 +++++++++++++++++++++++++++++++++++++++++++++++ week02/No589.java | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 week02/No1.java create mode 100644 week02/No589.java diff --git a/week02/NOTE.md b/week02/NOTE.md index 50de3041..cbd698f4 100644 --- a/week02/NOTE.md +++ b/week02/NOTE.md @@ -1 +1,31 @@ -学习笔记 \ No newline at end of file +学习笔记 +# HashMap 总结(jdk1.8) + ## 部分代码 + 1. 内部实现有链表结构 + ``` + static class Node implements Map.Entry { + final int hash; + final K key; + V value; + Node next; + + Node(int hash, K key, V value, Node next) { + this.hash = hash; + this.key = key; + this.value = value; + this.next = next; + } + + public final K getKey() { return key; } + public final V getValue() { return value; } + public final String toString() { return key + "=" + value; } + } + ``` + 2. 获取数据时,先判断有无结果,如有返回节点的值 + ``` + public V get(Object key) { + Node e; + return (e = getNode(hash(key), key)) == null ? null : e.value; + } + ``` + 3. containsValue 和 containsKey 都是对 Node[] 数据的遍历 diff --git a/week02/No1.java b/week02/No1.java new file mode 100644 index 00000000..fa034c42 --- /dev/null +++ b/week02/No1.java @@ -0,0 +1,52 @@ +package learning.algorithm.test; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * 说明: + * @date 2020/10/29 14:11 + */ +public class No1 { + @Test + public void testNums(){ + int[] _sum = new int[]{2,7,8,9}; + int[] result = twoSum(_sum,14); + for (int i : result) { + System.out.println(i); + } + } + + public int[] twoSum(int[] nums, int target) { + Map map = new HashMap<>(); + int[] result = new int[2]; + for (int i = 0; i < nums.length; i++) { + if(map.containsKey(target-nums[i])){ + result[0] = map.get(target-nums[i]); + result[1] = i; + }else{ + map.put(nums[i], i); + } + } + return result; + } +} +// 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 +// +// 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 +// +// +// +// 示例: +// +// 给定 nums = [2, 7, 11, 15], target = 9 +// +//因为 nums[0] + nums[1] = 2 + 7 = 9 +//所以返回 [0, 1] +// +// Related Topics 数组 哈希表 +// 👍 9419 👎 0 + + diff --git a/week02/No589.java b/week02/No589.java new file mode 100644 index 00000000..4d6761a9 --- /dev/null +++ b/week02/No589.java @@ -0,0 +1,39 @@ + +//给定一个 N 叉树,返回其节点值的前序遍历。 +// +// 例如,给定一个 3叉树 : +// +// 返回其前序遍历: [1,3,5,6,2,4]。 +// 说明: 递归法很简单,你可以使用迭代法完成此题吗? Related Topics 树 + +/* +// Definition for a Node. +class Node { + public int val; + public List children; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } +}; +*/ + + class Solution { + List list = new ArrayList(); + public List preorder(Node root) { + if(null==root) return list; + list.add(root.val); + for(Node node : root.children){ + preorder(node); + } + return list; + } + } + //leetcode submit region end(Prohibit modification and deletion) From 6b1dc998dd435da261904603f7c3724b7ec7896a Mon Sep 17 00:00:00 2001 From: ftqiao Date: Sat, 31 Oct 2020 11:09:11 +0800 Subject: [PATCH 04/14] homework --- week02/No144.java | 31 +++++++++++++++++++++++++++++++ week02/No242.java | 16 ++++++++++++++++ week02/No49.java | 21 +++++++++++++++++++++ week02/No94.java | 31 +++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 week02/No144.java create mode 100644 week02/No242.java create mode 100644 week02/No49.java create mode 100644 week02/No94.java diff --git a/week02/No144.java b/week02/No144.java new file mode 100644 index 00000000..f0eb37a6 --- /dev/null +++ b/week02/No144.java @@ -0,0 +1,31 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List preorderTraversal(TreeNode root) { + List res = new ArrayList(); + preorder(root, res); + return res; + } + + public void preorder(TreeNode root, List res) { + if (root == null) { + return; + } + res.add(root.val); + preorder(root.left, res); + preorder(root.right, res); + } +} diff --git a/week02/No242.java b/week02/No242.java new file mode 100644 index 00000000..e3076d1c --- /dev/null +++ b/week02/No242.java @@ -0,0 +1,16 @@ +class Solution { + public boolean isAnagram(String s, String t) { + int[] letterCount = new int[26]; + //统计字符串s中的每个字符的数量 + for (int i = 0; i < s.length(); i++) + letterCount[s.charAt(i) - 'a']++; + //减去字符串t中的每个字符的数量 + for (int i = 0; i < t.length(); i++) + letterCount[t.charAt(i) - 'a']--; + //如果数组letterCount的每个值都是0,返回true,否则返回false + for (int i : letterCount) + if (i != 0) + return false; + return true; + } +} diff --git a/week02/No49.java b/week02/No49.java new file mode 100644 index 00000000..94d77dce --- /dev/null +++ b/week02/No49.java @@ -0,0 +1,21 @@ +class Solution { + public List> groupAnagrams(String[] strs) { + //边界条件判断 + if (strs == null || strs.length == 0) + return new ArrayList<>(); + Map> map = new HashMap<>(); + for (String s : strs) { + char[] ca = new char[26]; + //统计字符串中每个字符串出现的次数 + for (char c : s.toCharArray()) + ca[c - 'a']++; + //统计每个字符出现次数的数组转化为字符串 + String keyStr = String.valueOf(ca); + if (!map.containsKey(keyStr)) + map.put(keyStr, new ArrayList<>()); + map.get(keyStr).add(s); + } + return new ArrayList<>(map.values()); +} + +} diff --git a/week02/No94.java b/week02/No94.java new file mode 100644 index 00000000..5147ddec --- /dev/null +++ b/week02/No94.java @@ -0,0 +1,31 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List inorderTraversal(TreeNode root) { + List res = new ArrayList(); + inorder(root, res); + return res; + } + + public void inorder(TreeNode root, List res) { + if (root == null) { + return; + } + inorder(root.left, res); + res.add(root.val); + inorder(root.right, res); + } +} From 52970f26ed0650bb30cbaeaab95e2de80609c396 Mon Sep 17 00:00:00 2001 From: fengt Date: Sat, 31 Oct 2020 20:30:30 +0800 Subject: [PATCH 05/14] week02 --- week02/No144.java | 31 +++++++++++++++++++++++++++++++ week02/No242.java | 16 ++++++++++++++++ week02/No49.java | 21 +++++++++++++++++++++ week02/No94.java | 31 +++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 week02/No144.java create mode 100644 week02/No242.java create mode 100644 week02/No49.java create mode 100644 week02/No94.java diff --git a/week02/No144.java b/week02/No144.java new file mode 100644 index 00000000..f0eb37a6 --- /dev/null +++ b/week02/No144.java @@ -0,0 +1,31 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List preorderTraversal(TreeNode root) { + List res = new ArrayList(); + preorder(root, res); + return res; + } + + public void preorder(TreeNode root, List res) { + if (root == null) { + return; + } + res.add(root.val); + preorder(root.left, res); + preorder(root.right, res); + } +} diff --git a/week02/No242.java b/week02/No242.java new file mode 100644 index 00000000..e3076d1c --- /dev/null +++ b/week02/No242.java @@ -0,0 +1,16 @@ +class Solution { + public boolean isAnagram(String s, String t) { + int[] letterCount = new int[26]; + //统计字符串s中的每个字符的数量 + for (int i = 0; i < s.length(); i++) + letterCount[s.charAt(i) - 'a']++; + //减去字符串t中的每个字符的数量 + for (int i = 0; i < t.length(); i++) + letterCount[t.charAt(i) - 'a']--; + //如果数组letterCount的每个值都是0,返回true,否则返回false + for (int i : letterCount) + if (i != 0) + return false; + return true; + } +} diff --git a/week02/No49.java b/week02/No49.java new file mode 100644 index 00000000..dc006cbd --- /dev/null +++ b/week02/No49.java @@ -0,0 +1,21 @@ +class Solution { + public List> groupAnagrams(String[] strs) { + //边界条件判断 + if (strs == null || strs.length == 0) + return new ArrayList<>(); + Map> map = new HashMap<>(); + for (String s : strs) { + char[] ca = new char[26]; + //统计字符串中每个字符串出现的次数 + for (char c : s.toCharArray()) + ca[c - 'a']++; + //统计每个字符出现次数的数组转化为字符串 + String keyStr = String.valueOf(ca); + if (!map.containsKey(keyStr)) + map.put(keyStr, new ArrayList<>()); + map.get(keyStr).add(s); + } + return new ArrayList<>(map.values()); + } + +} diff --git a/week02/No94.java b/week02/No94.java new file mode 100644 index 00000000..5147ddec --- /dev/null +++ b/week02/No94.java @@ -0,0 +1,31 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List inorderTraversal(TreeNode root) { + List res = new ArrayList(); + inorder(root, res); + return res; + } + + public void inorder(TreeNode root, List res) { + if (root == null) { + return; + } + inorder(root.left, res); + res.add(root.val); + inorder(root.right, res); + } +} From 020d62f0b174866f3f4977e1260950cc4bc3f327 Mon Sep 17 00:00:00 2001 From: ftqiao Date: Sat, 7 Nov 2020 10:35:55 +0800 Subject: [PATCH 06/14] week03 --- week03/N64.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++ week03/No236.java | 21 ++++++++++++++++++++ week03/No77.java | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 week03/N64.java create mode 100644 week03/No236.java create mode 100644 week03/No77.java diff --git a/week03/N64.java b/week03/N64.java new file mode 100644 index 00000000..b48674aa --- /dev/null +++ b/week03/N64.java @@ -0,0 +1,49 @@ +package learning.algorithm.test; + +import java.util.ArrayList; +import java.util.List; + +public class N64 { + public List> permute(int[] nums) { + int len = nums.length; + // 使用一个动态数组保存所有可能的全排列 + List> res = new ArrayList<>(); + if (len == 0) { + return res; + } + + boolean[] used = new boolean[len]; + List path = new ArrayList<>(); + + dfs(nums, len, 0, path, used, res); + return res; + } + + private void dfs(int[] nums, int len, int depth, + List path, boolean[] used, + List> 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); + } + } + } + + public static void main(String[] args) { + int[] nums = {1, 2, 3}; + N64 solution = new N64(); + List> lists = solution.permute(nums); + System.out.println(lists); + } + +} diff --git a/week03/No236.java b/week03/No236.java new file mode 100644 index 00000000..123767d2 --- /dev/null +++ b/week03/No236.java @@ -0,0 +1,21 @@ +package learning.algorithm.test; + +public class No236 { + 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) return right; + if(right == null) return left; + return root; + } +} +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ diff --git a/week03/No77.java b/week03/No77.java new file mode 100644 index 00000000..c7f7cbcc --- /dev/null +++ b/week03/No77.java @@ -0,0 +1,37 @@ +package learning.algorithm.test; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; + +public class No77 { + public List> combine(int n, int k) { + List> res = new ArrayList<>(); + if (k <= 0 || n < k) { + return res; + } + // 从 1 开始是题目的设定 + Deque path = new ArrayDeque<>(); + dfs(n, k, 1, path, res); + return res; + } + + private void dfs(int n, int k, int begin, Deque path, List> res) { + // 递归终止条件是:path 的长度等于 k + if (path.size() == k) { + res.add(new ArrayList<>(path)); + return; + } + // 遍历可能的搜索起点 + for (int i = begin; i <= n; i++) { + // 向路径变量里添加一个数 + path.addLast(i); + // 下一轮搜索,设置的搜索起点要加 1,因为组合数理不允许出现重复的元素 + dfs(n, k, i + 1, path, res); + // 重点理解这里:深度优先遍历有回头的过程,因此递归之前做了什么,递归之后需要做相同操作的逆向操作 + path.removeLast(); + } + } + +} From 74fda4a9fb43860a34bab636bb3783dd3fc97fee Mon Sep 17 00:00:00 2001 From: fengt Date: Fri, 13 Nov 2020 18:24:12 +0800 Subject: [PATCH 07/14] week04 --- week04/No122.java | 23 +++++++++++++++++++++++ week04/No455.java | 36 ++++++++++++++++++++++++++++++++++++ week04/No860.java | 30 ++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 week04/No122.java create mode 100644 week04/No455.java create mode 100644 week04/No860.java diff --git a/week04/No122.java b/week04/No122.java new file mode 100644 index 00000000..8aa42e9e --- /dev/null +++ b/week04/No122.java @@ -0,0 +1,23 @@ +package learning.algorithm.test; + +import org.junit.Test; +//时间复杂度O(n) +public class No122 { + @Test + public void testProfit() { + int[] params = {7, 1, 5, 3, 6, 4}; + int result = maxProfit(params); + System.out.println(result); + } + + public int maxProfit(int[] prices) { + int profit = 0; + for (int i = 1; i < prices.length; i++) { + int temp = prices[i] - prices[i - 1]; + if (temp > 0) { + profit += temp; + } + } + return profit; + } +} diff --git a/week04/No455.java b/week04/No455.java new file mode 100644 index 00000000..3744d640 --- /dev/null +++ b/week04/No455.java @@ -0,0 +1,36 @@ +package learning.algorithm.test; + +import org.junit.Test; + +import java.util.Arrays; + +/** + * 说明: + */ +public class No455 { + @Test + public void testFind() { + int[] gi = {1, 2, 3}; + int[] si = {1, 1}; + int result = findContentChildren(gi,si); + System.out.println(result); + } + + /** + * from lian-zhou + * 排序后,对每个小孩找饼,只要满足条件,就计数 + */ + public int findContentChildren(int[] g, int[] s) { + if (g == null || s == null) return 0; + Arrays.sort(g); + Arrays.sort(s); + int gi = 0, si = 0; + while (gi < g.length && si < s.length) { + if (g[gi] <= s[si]) gi++; + si++; + } + return gi; + } + + +} diff --git a/week04/No860.java b/week04/No860.java new file mode 100644 index 00000000..d777bf3e --- /dev/null +++ b/week04/No860.java @@ -0,0 +1,30 @@ +//空间复杂度O(1) +//时间复杂度O(n) +class Solution { + public boolean lemonadeChange(int[] bills) { + int five = 0; + int ten = 0; + int tewnty = 0; + for (int i = 0; i < bills.length; i++) { + if (bills[i] == 5) { + five++; + } else if (bills[i] == 10) { + ten++; + five--; + } else { + tewnty++; + if (ten == 0) { + five--; + five--; + } else { + ten--; + } + five--; + } + if (five < 0 || ten < 0) { + return false; + } + } + return true; + } +} From 1d4025d00e4b8af03d298eca4efc0c0eebabe126 Mon Sep 17 00:00:00 2001 From: fengt Date: Sat, 28 Nov 2020 21:03:05 +0800 Subject: [PATCH 08/14] week06 --- week06/No64.java | 22 ++++++++++++++++++++++ week06/No647.java | 32 ++++++++++++++++++++++++++++++++ week06/No91.java | 24 ++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 week06/No64.java create mode 100644 week06/No647.java create mode 100644 week06/No91.java diff --git a/week06/No64.java b/week06/No64.java new file mode 100644 index 00000000..9ee7f33c --- /dev/null +++ b/week06/No64.java @@ -0,0 +1,22 @@ +class Solution { + public int minPathSum(int[][] grid) { + if (grid == null || grid.length == 0 || grid[0].length == 0) { + return 0; + } + int rows = grid.length, columns = grid[0].length; + int[][] dp = new int[rows][columns]; + dp[0][0] = grid[0][0]; + for (int i = 1; i < rows; i++) { + dp[i][0] = dp[i - 1][0] + grid[i][0]; + } + for (int j = 1; j < columns; j++) { + dp[0][j] = dp[0][j - 1] + grid[0][j]; + } + for (int i = 1; i < rows; i++) { + for (int j = 1; j < columns; j++) { + dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; + } + } + return dp[rows - 1][columns - 1]; + } +} diff --git a/week06/No647.java b/week06/No647.java new file mode 100644 index 00000000..57ec4f9f --- /dev/null +++ b/week06/No647.java @@ -0,0 +1,32 @@ +class Solution { + public int countSubstrings(String s) { + int n = s.length(); + StringBuffer t = new StringBuffer("$#"); + for (int i = 0; i < n; ++i) { + t.append(s.charAt(i)); + t.append('#'); + } + n = t.length(); + t.append('!'); + + int[] f = new int[n]; + int iMax = 0, rMax = 0, ans = 0; + for (int i = 1; i < n; ++i) { + // 初始化 f[i] + f[i] = i <= rMax ? Math.min(rMax - i + 1, f[2 * iMax - i]) : 1; + // 中心拓展 + while (t.charAt(i + f[i]) == t.charAt(i - f[i])) { + ++f[i]; + } + // 动态维护 iMax 和 rMax + if (i + f[i] - 1 > rMax) { + iMax = i; + rMax = i + f[i] - 1; + } + // 统计答案, 当前贡献为 (f[i] - 1) / 2 上取整 + ans += f[i] / 2; + } + + return ans; + } +} diff --git a/week06/No91.java b/week06/No91.java new file mode 100644 index 00000000..f9c8d2c7 --- /dev/null +++ b/week06/No91.java @@ -0,0 +1,24 @@ +class Solution { + public int numDecodings(String s) { + if(s.charAt(0)=='0'){ + return 0; + } + int [] dp = new int [s.length()+1];//长度为n时,的排列组合种类 + dp[0] = 1; + dp[1] = 1; + if(s.length()==1) return dp[1]; + for(int i=2;i<=s.length();i++){ + int num = Integer.valueOf(String.valueOf(s.charAt(i-1)));//得到当前数; + int nums2 = Integer.valueOf(String.valueOf(s.charAt(i-2)));//得到当前数的前一个数 + if (nums2+num==0||(num==0&&nums2>2)){ + return 0; + }else if(num==0||nums2==0){ + dp[i] = num==0?dp[i-2]:dp[i-1]; + }else{ + dp[i] = nums2*10+num>26?dp[i-1]:dp[i-2]+dp[i-1]; + } + + } + return dp[s.length()]; + } +} From e64e915fd8045fb097a0957e5cbed7b407d9de71 Mon Sep 17 00:00:00 2001 From: ftqiao Date: Sat, 5 Dec 2020 17:05:26 +0800 Subject: [PATCH 09/14] week07 --- week07/No127.java | 80 +++++++++++++++++++++++++++++++++++++++++++++++ week07/No22.java | 47 ++++++++++++++++++++++++++++ week07/No547.java | 22 +++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 week07/No127.java create mode 100644 week07/No22.java create mode 100644 week07/No547.java diff --git a/week07/No127.java b/week07/No127.java new file mode 100644 index 00000000..03e861c2 --- /dev/null +++ b/week07/No127.java @@ -0,0 +1,80 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Set; + +public class Solution { + + public int ladderLength(String beginWord, String endWord, List wordList) { + // 第 1 步:先将 wordList 放到哈希表里,便于判断某个单词是否在 wordList 里 + Set wordSet = new HashSet<>(wordList); + if (wordSet.size() == 0 || !wordSet.contains(endWord)) { + return 0; + } + wordSet.remove(beginWord); + + // 第 2 步:图的广度优先遍历,必须使用队列和表示是否访问过的 visited 哈希表 + Queue queue = new LinkedList<>(); + queue.offer(beginWord); + Set visited = new HashSet<>(); + visited.add(beginWord); + + // 第 3 步:开始广度优先遍历,包含起点,因此初始化的时候步数为 1 + int step = 1; + while (!queue.isEmpty()) { + int currentSize = queue.size(); + for (int i = 0; i < currentSize; i++) { + // 依次遍历当前队列中的单词 + String currentWord = queue.poll(); + // 如果 currentWord 能够修改 1 个字符与 endWord 相同,则返回 step + 1 + if (changeWordEveryOneLetter(currentWord, endWord, queue, visited, wordSet)) { + return step + 1; + } + } + step++; + } + return 0; + } + + /** + * 尝试对 currentWord 修改每一个字符,看看是不是能与 endWord 匹配 + * + * @param currentWord + * @param endWord + * @param queue + * @param visited + * @param wordSet + * @return + */ + private boolean changeWordEveryOneLetter(String currentWord, String endWord, + Queue queue, Set visited, Set wordSet) { + char[] charArray = currentWord.toCharArray(); + for (int i = 0; i < endWord.length(); i++) { + // 先保存,然后恢复 + char originChar = charArray[i]; + for (char k = 'a'; k <= 'z'; k++) { + if (k == originChar) { + continue; + } + charArray[i] = k; + String nextWord = String.valueOf(charArray); + if (wordSet.contains(nextWord)) { + if (nextWord.equals(endWord)) { + return true; + } + if (!visited.contains(nextWord)) { + queue.add(nextWord); + // 注意:添加到队列以后,必须马上标记为已经访问 + visited.add(nextWord); + } + } + } + // 恢复 + charArray[i] = originChar; + } + return false; + } +} diff --git a/week07/No22.java b/week07/No22.java new file mode 100644 index 00000000..f3009622 --- /dev/null +++ b/week07/No22.java @@ -0,0 +1,47 @@ +import java.util.ArrayList; +import java.util.List; + +public class Solution { + + // 做减法 + + public List generateParenthesis(int n) { + List res = new ArrayList<>(); + // 特判 + if (n == 0) { + return res; + } + + // 执行深度优先遍历,搜索可能的结果 + dfs("", n, n, res); + return res; + } + + /** + * @param curStr 当前递归得到的结果 + * @param left 左括号还有几个可以使用 + * @param right 右括号还有几个可以使用 + * @param res 结果集 + */ + private void dfs(String curStr, int left, int right, List res) { + // 因为每一次尝试,都使用新的字符串变量,所以无需回溯 + // 在递归终止的时候,直接把它添加到结果集即可,注意与「力扣」第 46 题、第 39 题区分 + if (left == 0 && right == 0) { + res.add(curStr); + return; + } + + // 剪枝(如图,左括号可以使用的个数严格大于右括号可以使用的个数,才剪枝,注意这个细节) + if (left > right) { + return; + } + + if (left > 0) { + dfs(curStr + "(", left - 1, right, res); + } + + if (right > 0) { + dfs(curStr + ")", left, right - 1, res); + } + } +} diff --git a/week07/No547.java b/week07/No547.java new file mode 100644 index 00000000..e7107d88 --- /dev/null +++ b/week07/No547.java @@ -0,0 +1,22 @@ + +public class Solution { + public void dfs(int[][] M, int[] visited, int i) { + for (int j = 0; j < M.length; j++) { + if (M[i][j] == 1 && visited[j] == 0) { + visited[j] = 1; + dfs(M, visited, j); + } + } + } + public int findCircleNum(int[][] M) { + int[] visited = new int[M.length]; + int count = 0; + for (int i = 0; i < M.length; i++) { + if (visited[i] == 0) { + dfs(M, visited, i); + count++; + } + } + return count; + } +} From 2be15467fd9c87ec60a7bc151b30b30a3c410f60 Mon Sep 17 00:00:00 2001 From: fengt Date: Fri, 11 Dec 2020 13:51:35 +0800 Subject: [PATCH 10/14] week08 --- week08/1122.java | 29 +++++++++++++++++++++++ week08/No231.java | 23 ++++++++++++++++++ week08/No51.java | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 week08/1122.java create mode 100644 week08/No231.java create mode 100644 week08/No51.java diff --git a/week08/1122.java b/week08/1122.java new file mode 100644 index 00000000..81136455 --- /dev/null +++ b/week08/1122.java @@ -0,0 +1,29 @@ +class Solution { + public int[] relativeSortArray(int[] arr1, int[] arr2) { + //鉴于自定义排序的时间复杂度很高,所以采用计数循环的思路【以时间换空间】 + //1.遍历arr1,记录每个数出现的次数,记录数组长度为【1001】 + //2.将arr2中出现的数加入结果数组 + //3.将arr2中没出现的数加入结果数组(记录数组本身就是升序的,0-1001) + int[] res = new int[arr1.length]; + int index = 0; + int[] times = new int[1001]; //因为数范围在0-1000 + for (int num : arr1) times[num]++; //遍历arr1 + for (int num : arr2) { //遍历arr2 + while (times[num] > 0) { + res[index++] = num; + times[num]--; + } + } + for (int i = 0; i < times.length; i++) { + while (times[i] > 0) { + res[index++] = i; + times[i]--; + } + } + return res; + } +} +// 作者:sunflower-zzn +// 链接:https://leetcode-cn.com/problems/relative-sort-array/solution/javasan-chong-jie-fa-zi-ding-yi-pai-xu-ji-shu-pai-/ +// 来源:力扣(LeetCode) +// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 diff --git a/week08/No231.java b/week08/No231.java new file mode 100644 index 00000000..82807641 --- /dev/null +++ b/week08/No231.java @@ -0,0 +1,23 @@ +/** + * 时间复杂度为 O(logN)O(logN) + */ +//class Solution { +// public boolean isPowerOfTwo(int n) { +// if (n == 0) return false; +// while (n % 2 == 0) n /= 2; +// return n == 1; +// } +//} + + +/** + * 时间复杂度:O(1)O(1)。 + * 空间复杂度:O(1)O(1)。 + */ +class Solution { + public boolean isPowerOfTwo(int n) { + if (n == 0) return false; + long x = (long) n; + return (x & (x - 1)) == 0; + } +} diff --git a/week08/No51.java b/week08/No51.java new file mode 100644 index 00000000..d5cbfb9b --- /dev/null +++ b/week08/No51.java @@ -0,0 +1,60 @@ +class Solution { + public List> solveNQueens(int n) { + char[][] chess = new char[n][n]; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + chess[i][j] = '.'; + List> res = new ArrayList<>(); + solve(res, chess, 0); + return res; + } + + private void solve(List> res, char[][] chess, int row) { + if (row == chess.length) { + res.add(construct(chess)); + return; + } + for (int col = 0; col < chess.length; col++) { + if (valid(chess, row, col)) { + chess[row][col] = 'Q'; + solve(res, chess, row + 1); + chess[row][col] = '.'; + } + } + } + + //row表示第几行,col表示第几列 + private boolean valid(char[][] chess, int row, int col) { + //判断当前列有没有皇后,因为他是一行一行往下走的, + //我们只需要检查走过的行数即可,通俗一点就是判断当前 + //坐标位置的上面有没有皇后 + for (int i = 0; i < row; i++) { + if (chess[i][col] == 'Q') { + return false; + } + } + //判断当前坐标的右上角有没有皇后 + for (int i = row - 1, j = col + 1; i >= 0 && j < chess.length; i--, j++) { + if (chess[i][j] == 'Q') { + return false; + } + } + //判断当前坐标的左上角有没有皇后 + for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { + if (chess[i][j] == 'Q') { + return false; + } + } + return true; + } + + //把数组转为list + private List construct(char[][] chess) { + List path = new ArrayList<>(); + for (int i = 0; i < chess.length; i++) { + path.add(new String(chess[i])); + } + return path; + } + +} From afa4d995b1c12375eb18d46d64e34a8d0e1ec9e4 Mon Sep 17 00:00:00 2001 From: ftqiao Date: Tue, 15 Dec 2020 13:21:01 +0800 Subject: [PATCH 11/14] Added Untitled Diagram.drawio --- week01/Untitled Diagram.drawio | 1 + 1 file changed, 1 insertion(+) create mode 100644 week01/Untitled Diagram.drawio diff --git a/week01/Untitled Diagram.drawio b/week01/Untitled Diagram.drawio new file mode 100644 index 00000000..03665804 --- /dev/null +++ b/week01/Untitled Diagram.drawio @@ -0,0 +1 @@ +7ZjLcpswFIafhmU6RhgbL2Pn0kU6yTSdSbOU4QTUCMQIEeM+fSUQYC5OcGrctNOVpV8XxP/pnMPYsFZhds1xHHxhHlADTbzMsC4MhEyELPmjlK1WTAcVis+Jp7VauCc/QYsTrabEg6QxUTBGBYmbosuiCFzR0DDnbNOc9sRo86kx9qEj3LuYdtUH4omgUB17UuufgfhB+WRzokdCXE7WQhJgj212JOvSsFacMVG0wmwFVLlX+lKsu9ozWh2MQySGLLCidHmV8YW7vZnE0e3DN4Svz/QuL5im+oUN6/x2/UNZWZxabEsr5AvEqpmG9IY8ASWR7C1j4CQEAVyOUC3f1dpSghFYamrczPuU4jgh63zbiVQ4uClPyAt8haTgn6ssjTzwdK8yL+8Izp4rHGpT/RbABWR77TEr0+V1BSYPyLdySnVXNSd9Ux3d3dTUK7bBDnGrFLG+aX61dQ1DNjSPA9igLps2kpiRSOTPtZeGfdHCwbgImM8iTHeBHN/Y/Tdrr9tTu2H2vM/srtfmYiyvrY7XHkliLNyg47kyg8gEcU6JH0lpzYRgYe4e5uJc5RzlvdxKahB5pbKmzH0up+lE5wwlAF4nTQ3xXyZLzH14bR7q58SBYiFjsplQe2zXS+/UTaz5npn9gMsdEpZyF/SiFrvqFO/HOf2HQ8du5qkqb70RO85YoWP/LyFZqxR8mBIy+6vjwD6khPSa3VNCZmN5Pe94zUGkPBpeQHaKBYtBDi09nAS5z2YxvFM2ICPiuzZdtR9V+9PCfndFKVLy25dpWEUZFDe/WWTQvHkFkDVrblEcdbQq4xzho6HnA0G6xrcVWtV5PCTSDgeLBoKd/SmwnaAd+fNh0QEr0dE1lniOAtY8EdihETs9Gdhps0KiduUbGWxZEU6dpM2TJenph4vlNnJ7fqQkLbv1vyfF9PpPKOvyFw== \ No newline at end of file From fdbcad330e7b0019d5d4235059b6f6599c0fd855 Mon Sep 17 00:00:00 2001 From: ftqiao Date: Tue, 15 Dec 2020 13:21:20 +0800 Subject: [PATCH 12/14] Update Untitled Diagram.drawio --- week01/Untitled Diagram.drawio | 51 +++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/week01/Untitled Diagram.drawio b/week01/Untitled Diagram.drawio index 03665804..8249d5da 100644 --- a/week01/Untitled Diagram.drawio +++ b/week01/Untitled Diagram.drawio @@ -1 +1,50 @@ -7ZjLcpswFIafhmU6RhgbL2Pn0kU6yTSdSbOU4QTUCMQIEeM+fSUQYC5OcGrctNOVpV8XxP/pnMPYsFZhds1xHHxhHlADTbzMsC4MhEyELPmjlK1WTAcVis+Jp7VauCc/QYsTrabEg6QxUTBGBYmbosuiCFzR0DDnbNOc9sRo86kx9qEj3LuYdtUH4omgUB17UuufgfhB+WRzokdCXE7WQhJgj212JOvSsFacMVG0wmwFVLlX+lKsu9ozWh2MQySGLLCidHmV8YW7vZnE0e3DN4Svz/QuL5im+oUN6/x2/UNZWZxabEsr5AvEqpmG9IY8ASWR7C1j4CQEAVyOUC3f1dpSghFYamrczPuU4jgh63zbiVQ4uClPyAt8haTgn6ssjTzwdK8yL+8Izp4rHGpT/RbABWR77TEr0+V1BSYPyLdySnVXNSd9Ux3d3dTUK7bBDnGrFLG+aX61dQ1DNjSPA9igLps2kpiRSOTPtZeGfdHCwbgImM8iTHeBHN/Y/Tdrr9tTu2H2vM/srtfmYiyvrY7XHkliLNyg47kyg8gEcU6JH0lpzYRgYe4e5uJc5RzlvdxKahB5pbKmzH0up+lE5wwlAF4nTQ3xXyZLzH14bR7q58SBYiFjsplQe2zXS+/UTaz5npn9gMsdEpZyF/SiFrvqFO/HOf2HQ8du5qkqb70RO85YoWP/LyFZqxR8mBIy+6vjwD6khPSa3VNCZmN5Pe94zUGkPBpeQHaKBYtBDi09nAS5z2YxvFM2ICPiuzZdtR9V+9PCfndFKVLy25dpWEUZFDe/WWTQvHkFkDVrblEcdbQq4xzho6HnA0G6xrcVWtV5PCTSDgeLBoKd/SmwnaAd+fNh0QEr0dE1lniOAtY8EdihETs9Gdhps0KiduUbGWxZEU6dpM2TJenph4vlNnJ7fqQkLbv1vyfF9PpPKOvyFw== \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 925683ecb98930403840b98d531fe2ce09fb6cb6 Mon Sep 17 00:00:00 2001 From: fengt Date: Fri, 18 Dec 2020 16:05:13 +0800 Subject: [PATCH 13/14] week09 --- week09/No5.java | 39 +++++++++++++++++++++++++++++++++++++++ week09/No541.java | 15 +++++++++++++++ week09/No8.java | 43 +++++++++++++++++++++++++++++++++++++++++++ week09/No917.java | 19 +++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 week09/No5.java create mode 100644 week09/No541.java create mode 100644 week09/No8.java create mode 100644 week09/No917.java diff --git a/week09/No5.java b/week09/No5.java new file mode 100644 index 00000000..4e9f73e2 --- /dev/null +++ b/week09/No5.java @@ -0,0 +1,39 @@ +public class Solution { + + public String longestPalindrome(String s) { + int len = s.length(); + if (len < 2) { + return s; + } + + int maxLen = 1; + int begin = 0; + // s.charAt(i) 每次都会检查数组下标越界,因此先转换成字符数组 + char[] charArray = s.toCharArray(); + + // 枚举所有长度大于 1 的子串 charArray[i..j] + for (int i = 0; i < len - 1; i++) { + for (int j = i + 1; j < len; j++) { + if (j - i + 1 > maxLen && validPalindromic(charArray, i, j)) { + maxLen = j - i + 1; + begin = i; + } + } + } + return s.substring(begin, begin + maxLen); + } + + /** + * 验证子串 s[left..right] 是否为回文串 + */ + private boolean validPalindromic(char[] charArray, int left, int right) { + while (left < right) { + if (charArray[left] != charArray[right]) { + return false; + } + left++; + right--; + } + return true; + } +} diff --git a/week09/No541.java b/week09/No541.java new file mode 100644 index 00000000..82ba3e69 --- /dev/null +++ b/week09/No541.java @@ -0,0 +1,15 @@ + +class Solution { + public String reverseStr(String s, int k) { + char[] a = s.toCharArray(); + for (int start = 0; start < a.length; start += 2 * k) { + int i = start, j = Math.min(start + k - 1, a.length - 1); + while (i < j) { + char tmp = a[i]; + a[i++] = a[j]; + a[j--] = tmp; + } + } + return new String(a); + } +} diff --git a/week09/No8.java b/week09/No8.java new file mode 100644 index 00000000..db33aea5 --- /dev/null +++ b/week09/No8.java @@ -0,0 +1,43 @@ +class Solution { + public int myAtoi(String s) { + int index = 0; + int sign = 1; + int total = 0; + if (s.length() == 0) { + return 0; + } + + // 移除左侧的空格 + while (index < s.length() && s.charAt(index) == ' ') { + index++; + } + + if (index >= s.length()) { + return 0; + } + + // 找到正负号 + if (s.charAt(index) == '+' || s.charAt(index) == '-') { + sign = s.charAt(index) == '-' ? -1 : 1; + index++; + } + + while (index < s.length()) { + int digit = s.charAt(index) - '0'; + if (digit < 0 || digit > 9) { + break; + } + + if (Integer.MAX_VALUE / 10 < total + || (Integer.MAX_VALUE / 10 == total && Integer.MAX_VALUE % 10 < digit)) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + + total = total * 10 + digit; + index++; + } + + return total * sign; + } + +} diff --git a/week09/No917.java b/week09/No917.java new file mode 100644 index 00000000..84ed9840 --- /dev/null +++ b/week09/No917.java @@ -0,0 +1,19 @@ +class Solution { + public String reverseOnlyLetters(String S) { + Stack letters = new Stack(); + for (char c: S.toCharArray()) + if (Character.isLetter(c)) + letters.push(c); + + StringBuilder ans = new StringBuilder(); + for (char c: S.toCharArray()) { + if (Character.isLetter(c)) + ans.append(letters.pop()); + else + ans.append(c); + } + + return ans.toString(); + } +} + From 71cb379f50fb601cd93282031474ec4f6e5e7ff3 Mon Sep 17 00:00:00 2001 From: fengt Date: Mon, 28 Dec 2020 09:22:02 +0800 Subject: [PATCH 14/14] week10 --- week10/NOTE.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/week10/NOTE.md b/week10/NOTE.md index 50de3041..a914bda3 100644 --- a/week10/NOTE.md +++ b/week10/NOTE.md @@ -1 +1,6 @@ -学习笔记 \ No newline at end of file +学习笔记 + +课程总体安排还是比较合理的,有日常工作的情况下,坚持下来是很难的。难的算法往往一道题目就会耗费很久的时间。 +所幸,有老师提供的方法论,整体指导思想“孰能生巧”。 +* 不死磕,多看,多练,坚持! +这个行当,不是学会了算法就能够满足日常工作需要的,需要持续学习,甚至终身学习。接下来,希望自己能够坚持学习,有更多的收获。