From e66f8e98e2c13b1a4431e182d826443f617dbc36 Mon Sep 17 00:00:00 2001 From: liuchao Date: Thu, 23 May 2019 17:34:33 +0800 Subject: [PATCH 01/43] =?UTF-8?q?leetCode=20=E7=AE=80=E5=8D=95=E7=BA=A7?= =?UTF-8?q?=E5=88=AB=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=202019=E5=B9=B45?= =?UTF-8?q?=E6=9C=8823=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - java/src/juejin/lc/leetCode/IntToRoman.java | 22 +++ .../lc/leetCode/IsValidParentheses.java | 59 ++++++++ .../lc/leetCode/LongestCommonPrefix.java | 42 ++++++ .../src/juejin/lc/leetCode/MergeTwoLists.java | 81 +++++++++++ .../src/juejin/lc/leetCode/NumberReverse.java | 101 ++++++++++++++ .../juejin/lc/leetCode/RemoveDuplicates.java | 37 +++++ java/src/juejin/lc/leetCode/RomanToInt.java | 128 ++++++++++++++++++ 8 files changed, 470 insertions(+), 1 deletion(-) create mode 100644 java/src/juejin/lc/leetCode/IntToRoman.java create mode 100644 java/src/juejin/lc/leetCode/IsValidParentheses.java create mode 100644 java/src/juejin/lc/leetCode/LongestCommonPrefix.java create mode 100644 java/src/juejin/lc/leetCode/MergeTwoLists.java create mode 100644 java/src/juejin/lc/leetCode/NumberReverse.java create mode 100644 java/src/juejin/lc/leetCode/RemoveDuplicates.java create mode 100644 java/src/juejin/lc/leetCode/RomanToInt.java diff --git a/README.md b/README.md index 4c9fd48..95b8bcd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ # Progress Every Day - ## 传送门 ### [正则表达式匹配算法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/Pattern.java) ### [AVL树](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/tree/AVLTree.java) diff --git a/java/src/juejin/lc/leetCode/IntToRoman.java b/java/src/juejin/lc/leetCode/IntToRoman.java new file mode 100644 index 0000000..3a5c013 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IntToRoman.java @@ -0,0 +1,22 @@ +package juejin.lc.leetCode; + +/** + * 整数转罗马数字 + * @author liuchao + * @date 2019/5/23 + */ +public class IntToRoman { + public String intToRoman(int num) { + int values[]={1000,900,500,400,100,90,50,40,10,9,5,4,1}; + String reps[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; + + String res = ""; + for(int i=0; i<13; i++){ + while(num>=values[i]){ + num -= values[i]; + res += reps[i]; + } + } + return res; + } +} diff --git a/java/src/juejin/lc/leetCode/IsValidParentheses.java b/java/src/juejin/lc/leetCode/IsValidParentheses.java new file mode 100644 index 0000000..30b1e35 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsValidParentheses.java @@ -0,0 +1,59 @@ +package juejin.lc.leetCode; + +import java.util.Stack; + +/** + * 判断是否是有效括号 + * + * @author liuchao + * @date 2019/5/23 + */ +public class IsValidParentheses { + /** + * 规则 + * () true + * ()[]{} true + * {[]} true + * (] false + * ([)] false + * + * @param s 字符串 + * @return 返回结果 + */ + public boolean isValid(String s) { + Stack stack = new Stack<>(); + char[] chars = s.toCharArray(); + for (char c : chars) { + if (stack.isEmpty()){ + stack.push(c); + }else if (checkFull(stack.peek(),c)){ + stack.pop(); + }else{ + stack.push(c); + } + } + if (stack.isEmpty()){ + return true; + } + return false; + } + + /** + * 校验是否完整 + * @param prev 栈里的 + * @param current 当前 + * @return 返回结果 + */ + private boolean checkFull(Character prev, char current) { + return (prev == '(' && current == ')') || (prev == '[' && current == ']') || (prev == '{' && current == '}'); + } + + public static void main(String[] args) { + IsValidParentheses isValidParentheses = new IsValidParentheses(); + System.out.println(isValidParentheses.isValid("()[]{}")); + System.out.println(isValidParentheses.isValid("()")); + System.out.println(isValidParentheses.isValid("{[]}")); + System.out.println(isValidParentheses.isValid("(]")); + System.out.println(isValidParentheses.isValid("([)]")); + } +} diff --git a/java/src/juejin/lc/leetCode/LongestCommonPrefix.java b/java/src/juejin/lc/leetCode/LongestCommonPrefix.java new file mode 100644 index 0000000..49791e2 --- /dev/null +++ b/java/src/juejin/lc/leetCode/LongestCommonPrefix.java @@ -0,0 +1,42 @@ +package juejin.lc.leetCode; + +/** + * 编写一个函数来查找字符串数组中的最长公共前缀。 + * 如果不存在公共前缀,返回空字符串 ""。 + * + * @author liuchao + * @date 2019/5/23 + */ +public class LongestCommonPrefix { + public String longestCommonPrefix(String[] strs) { + if (strs.length == 1) { + return strs[0]; + } + StringBuilder sb = new StringBuilder(); + if (strs.length > 1) { + System.out.println("length:" + (strs.length - 1)); + int len = strs[0].length(); + for (int i = 0; i < len; i++) { + char curr = strs[0].charAt(i); + System.out.println("第" + i + "次:" + curr); + for (int j = 1; j < strs.length; j++) { + System.out.println("匹配字符串:" + strs[j].charAt(i)); + if (strs[j].length() <= i || strs[j].charAt(i) != curr) { + return sb.toString(); + } + System.out.println("i=" + i + ",j=" + j); + if (strs[j].charAt(i) == curr && j == strs.length - 1) { + sb.append(curr); + } + } + } + } + return sb.toString(); + } + + public static void main(String[] args) { + LongestCommonPrefix longestCommonPrefix = new LongestCommonPrefix(); + String[] strs = {"flower", "flow", "flight"}; + System.out.println(longestCommonPrefix.longestCommonPrefix(strs)); + } +} diff --git a/java/src/juejin/lc/leetCode/MergeTwoLists.java b/java/src/juejin/lc/leetCode/MergeTwoLists.java new file mode 100644 index 0000000..5bcc6aa --- /dev/null +++ b/java/src/juejin/lc/leetCode/MergeTwoLists.java @@ -0,0 +1,81 @@ +package juejin.lc.leetCode; + +/** + * 合并两个有序链表 + * 1 -> 2 -> 4 1 -> 3 -> 4 + * 1 -> 1 -> 2 -> 3 -> 4 -> 4 + * + * @author liuchao + * @date 2019/5/23 + */ +public class MergeTwoLists { + /** + * 合并两个有序链表 + * + * @param l1 链表1 + * @param l2 链表2 + * @return 返回合并后的链表 + */ + public ListNode solution(ListNode l1, ListNode l2) { + //边界条件判断 + if (null == l1) { + return l2; + } + if (null == l2) { + return l1; + } + ListNode lNode = l1; + ListNode rNode = l2; + ListNode node = null; + if (lNode.val > rNode.val) { + node = new ListNode(rNode.val); + rNode = rNode.next; + } else { + node = new ListNode(lNode.val); + lNode = lNode.next; + } + ListNode temp = node; + while (null != lNode && null != rNode) { + if (lNode.val > rNode.val) { + temp.next = rNode; + rNode = rNode.next; + } else { + temp.next = lNode; + lNode = lNode.next; + } + temp = temp.next; + } + if (null != lNode) { + temp.next = lNode; + } + if (null != rNode) { + temp.next = rNode; + } + return node; + } + + + public static class ListNode { + int val; + ListNode next; + + ListNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + MergeTwoLists mergeTwoLists = new MergeTwoLists(); + ListNode l1 = new ListNode(1); + l1.next = new ListNode(2); + l1.next.next = new ListNode(4); + ListNode l2 = new ListNode(1); + l2.next = new ListNode(3); + l2.next.next = new ListNode(4); + ListNode res = mergeTwoLists.solution(l1, l2); + while (null != res) { + System.out.print(res.val + " "); + res = res.next; + } + } +} diff --git a/java/src/juejin/lc/leetCode/NumberReverse.java b/java/src/juejin/lc/leetCode/NumberReverse.java new file mode 100644 index 0000000..d159a2a --- /dev/null +++ b/java/src/juejin/lc/leetCode/NumberReverse.java @@ -0,0 +1,101 @@ +package juejin.lc.leetCode; + +/** + * 整数反转 + * 各种回文 + * + * @author liuchao + * @date 2019/5/22 + */ +public class NumberReverse { + /** + * 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 + * 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。 + * 请根据这个假设,如果反转后整数溢出那么就返回 0。 + * + * @param x 传入整数 + */ + private static int reverse(int x) { + int rev = 0; + while (x != 0) { + int pop = x % 10; + x /= 10; + if (rev > Integer.MAX_VALUE / 10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) { + return 0; + } + if (rev < Integer.MIN_VALUE / 10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) { + return 0; + } + rev = rev * 10 + pop; + } + return rev; + } + + /** + * 判断是否是回文数 + * 并且不将其转成字符串 + * + * @param x 传入整数 + * @return 返回结果 + */ + private static boolean isPalindrome(int x) { + if (x >= 0) { + String str = String.valueOf(x); + if (x < 10 || str.equals(new StringBuilder(str).reverse().toString())) { + return true; + } + } + return false; + } + + /** + * 判断链表是否回文 + * 快慢指针法 + * @param head 链表 + * @return 返回值 + */ + private boolean isPalindrome(ListNode head) { + if (head == null || head.next == null) { + return true; + } + ListNode slow = head; + ListNode fast = head; + while (null != fast.next && null != fast.next.next){ + slow = slow.next; + fast = fast.next.next; + } + slow = slow.next; + ListNode prev = null; + while (null != slow){ + ListNode next = slow.next; + slow.next = prev; + prev = slow; + slow = next; + } + while (null != prev){ + if (head.val != prev.val){ + return false; + } + head = head.next; + prev = prev.next; + } + return true; + } + + private class ListNode { + int val; + ListNode next; + ListNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + //max = 2147483647 + int max = Integer.MAX_VALUE; + //min = -2147483648 + int min = Integer.MIN_VALUE; + System.out.println(reverse(max)); + System.out.println(reverse(min)); + } +} diff --git a/java/src/juejin/lc/leetCode/RemoveDuplicates.java b/java/src/juejin/lc/leetCode/RemoveDuplicates.java new file mode 100644 index 0000000..4129237 --- /dev/null +++ b/java/src/juejin/lc/leetCode/RemoveDuplicates.java @@ -0,0 +1,37 @@ +package juejin.lc.leetCode; + +/** + * 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 + * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 + * + * @author liuchao + * @date 2019/5/23 + */ +public class RemoveDuplicates { + /** + * 原地去重,返回新长度 + * + * @param nums 数组 + * @return 新数组长度 + */ + public int solution(int[] nums) { + int index = 0; + for (int i = 1; i < nums.length; i++) { + if (nums[i] == nums[i - 1]){ + ++index; + continue; + } + if (index > 0) { + nums[i - index] = nums[i]; + } + } + return nums.length - index; + } + + public static void main(String[] args) { + int[] nums = {1,1,2}; + RemoveDuplicates removeDuplicates = new RemoveDuplicates(); + int length = removeDuplicates.solution(nums); + System.out.println("length = " + length); + } +} diff --git a/java/src/juejin/lc/leetCode/RomanToInt.java b/java/src/juejin/lc/leetCode/RomanToInt.java new file mode 100644 index 0000000..85a1f79 --- /dev/null +++ b/java/src/juejin/lc/leetCode/RomanToInt.java @@ -0,0 +1,128 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 罗马数字转整数 + * I 1 + * V 5 + * X 10 + * L 50 + * C 100 + * D 500 + * M 1000 + * + * @author liuchao + * @date 2019/5/22 + */ +public class RomanToInt { + /** + * 规则 + * I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 + * X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 + * C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 + * + * @param s 字符串 + * @return 返回值 + */ + private int solution(String s) { + Map map = initDictionary(); + //临时变量,存储前一位 + char temp = s.charAt(0); + String[] strs = new String[s.length()]; + int index = 0; + for (int i = 1; i < s.length(); i++) { + char cur = s.charAt(i); + if (temp != '\0') { + if (checkCombo(temp, cur)) { + strs[index++] = temp + "" + cur; + temp = '\0'; + } else { + strs[index++] = temp + ""; + temp = cur; + } + } else { + temp = cur; + } + } + if (temp != 0) { + strs[index] = temp + ""; + } + int sums = 0; + for (int i = 0; i < strs.length; i++) { + if (null != strs[i]) { + sums += map.get(strs[i]); + } + } + return sums; + } + + /** + * 判断当前字符是否可以组合 + * + * @param prev 前 + * @param current 当前 + * @return 返回结果 + */ + private boolean checkCombo(char prev, char current) { + String expression = String.valueOf(prev); + String str = String.valueOf(current); + switch (expression) { + case "I": + //IV 4 IX 9 + if ("V".equals(str) || "X".equals(str)) { + return true; + } + break; + case "X": + // XL 40 XC 90 + if ("L".equals(str) || "C".equals(str)) { + return true; + } + break; + case "C": + // CD 400 CM 900 + if ("D".equals(str) || "M".equals(str)) { + return true; + } + break; + default: + break; + } + return false; + } + + /** + * 声明一个罗马数组关系映射的字典 + * + * @return map对象 + */ + private Map initDictionary() { + Map map = new HashMap<>(); + map.put("I", 1); + map.put("IV", 4); + map.put("V", 5); + map.put("IX", 9); + map.put("X", 10); + map.put("XL", 40); + map.put("L", 50); + map.put("XC", 90); + map.put("C", 100); + map.put("CD", 400); + map.put("D", 500); + map.put("CM", 900); + map.put("M", 1000); + return map; + } + + public static void main(String[] args) { + //2019 + String s = "MCMXCIV"; + RomanToInt romanToInt = new RomanToInt(); + int result = romanToInt.solution(s); + System.out.println(result); + } +} From ece30ce49fc9c47d2eea3c7ae47d96b0d5a22ffa Mon Sep 17 00:00:00 2001 From: liuchao Date: Fri, 24 May 2019 18:15:10 +0800 Subject: [PATCH 02/43] =?UTF-8?q?leetCode=20=E7=AE=80=E5=8D=95=E7=BA=A7?= =?UTF-8?q?=E5=88=AB=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=202019=E5=B9=B45?= =?UTF-8?q?=E6=9C=8824=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/ClimbStairs.java | 49 ++++++++++++++ java/src/juejin/lc/leetCode/CountAndSay.java | 64 +++++++++++++++++++ .../juejin/lc/leetCode/MargeTwoArrays.java | 50 +++++++++++++++ .../src/juejin/lc/leetCode/RemoveElement.java | 39 +++++++++++ java/src/juejin/lc/leetCode/SearchInsert.java | 48 ++++++++++++++ .../juejin/lc/leetCode/StrStrSolution.java | 45 +++++++++++++ 6 files changed, 295 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/ClimbStairs.java create mode 100644 java/src/juejin/lc/leetCode/CountAndSay.java create mode 100644 java/src/juejin/lc/leetCode/MargeTwoArrays.java create mode 100644 java/src/juejin/lc/leetCode/RemoveElement.java create mode 100644 java/src/juejin/lc/leetCode/SearchInsert.java create mode 100644 java/src/juejin/lc/leetCode/StrStrSolution.java diff --git a/java/src/juejin/lc/leetCode/ClimbStairs.java b/java/src/juejin/lc/leetCode/ClimbStairs.java new file mode 100644 index 0000000..48e6e29 --- /dev/null +++ b/java/src/juejin/lc/leetCode/ClimbStairs.java @@ -0,0 +1,49 @@ +package juejin.lc.leetCode; + +import java.util.HashMap; +import java.util.Map; + +/** + * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 + * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? + * 注意:给定 n 是一个正整数。 + * @author liuchao + * @date 2019/5/24 + */ +public class ClimbStairs { + public int solution(int n){ + int[] arrs = new int[n + 1]; + return recursion(arrs,n); + } + + public int climbStairs2(int n){ + if (n == 1) { + return 1; + } + int[] arrs = new int[n + 1]; + arrs[1] = 1; + arrs[2] = 2; + for (int i = 3; i <= n; i++) { + arrs[i] = arrs[i - 1] + arrs[i - 2]; + System.out.println("arrs[" + i + "] = " + arrs[i]); + } + return arrs[n]; + } + private int recursion(int[] arrs, int n) { + if (n < 3){ + return n; + } + if (arrs[n] > 0){ + return arrs[n]; + }else{ + arrs[n] = recursion(arrs,n - 1) + recursion(arrs,n - 2); + } + return arrs[n]; + } + + public static void main(String[] args) { + ClimbStairs climbStairs = new ClimbStairs(); + int n = 4; + System.out.println(climbStairs.climbStairs2(n)); + } +} diff --git a/java/src/juejin/lc/leetCode/CountAndSay.java b/java/src/juejin/lc/leetCode/CountAndSay.java new file mode 100644 index 0000000..c0bc4dc --- /dev/null +++ b/java/src/juejin/lc/leetCode/CountAndSay.java @@ -0,0 +1,64 @@ +package juejin.lc.leetCode; + +/** + * 1 被读作 "one 1" ("一个一") , 即 11。 + * 11 被读作 "two 1s" ("两个一"), 即 21。 + * 21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。 + * #TODO 迷迷糊糊 + * @author liuchao + * @date 2019/5/24 + */ +public class CountAndSay { + /** + * 1 1 + * 4 1211 + * + * @param n key + * @return value + */ + public String countAndSay(int n) { + StringBuffer result = new StringBuffer(); + String temp = ""; + + if (n == 1) { + return "1"; + } + if (n == 2) { + return "11"; + } + if (n == 3) { + return "21"; + } + if (n >= 4) { + temp = countAndSay(n - 1); + } + System.out.println("temp = " + temp); + int check = 1; + char c = temp.charAt(0); + for (int i = 1; i < temp.length(); i++) { + System.out.println("check = " + check + ",c = " + c + ",temp[" + i + "] = " + temp.charAt(i)); + if (temp.charAt(i) == c) { + check++; + continue; + } + if (temp.charAt(i) != c) { + result.append(check); + result.append(c); + check = 1; + c = temp.charAt(i); + } + } + System.out.println("check = " + check + ",c = " + c); + System.out.println("result-before = " + result); + result.append(check); + result.append(c); + System.out.println("result-after = " + result); + return result.toString(); + } + + public static void main(String[] args) { + CountAndSay countAndSay = new CountAndSay(); + int n = 5; + System.out.println("n = " + n + ",result = " + countAndSay.countAndSay(n)); + } +} diff --git a/java/src/juejin/lc/leetCode/MargeTwoArrays.java b/java/src/juejin/lc/leetCode/MargeTwoArrays.java new file mode 100644 index 0000000..cb261cb --- /dev/null +++ b/java/src/juejin/lc/leetCode/MargeTwoArrays.java @@ -0,0 +1,50 @@ +package juejin.lc.leetCode; + + +/** + * 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。 + * 说明: + * 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。 + * 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。 + * + * @author liuchao + * @date 2019/5/24 + */ +public class MargeTwoArrays { + /** + * 输入: + * nums1 = [1,2,3,0,0,0], m = 3 + * nums2 = [2,5,6], n = 3 + * 输出: [1,2,2,3,5,6] + * + * @param nums1 + * @param m + * @param nums2 + * @param n + */ + public int[] merge(int[] nums1, int m, int[] nums2, int n) { + if (nums1.length == 0) { + return nums2; + } + if (nums2.length == 0) { + return nums1; + } + int num = m + n - 1; + int i = m - 1; + int j = n - 1; + while (j >= 0) { + nums1[num--] = i >= 0 && nums1[i] > nums2[j] ? nums1[i--] : nums2[j--]; + } + return nums1; + } + + public static void main(String[] args) { + int[] nums1 = {1, 2, 3, 0, 0, 0}; + int m = 3; + int[] nums2 = {2, 5, 6}; + int n = 3; + MargeTwoArrays margeTwoArrays = new MargeTwoArrays(); + int[] res = margeTwoArrays.merge(nums1, m, nums2, n); + System.out.println(res.length); + } +} diff --git a/java/src/juejin/lc/leetCode/RemoveElement.java b/java/src/juejin/lc/leetCode/RemoveElement.java new file mode 100644 index 0000000..fb68297 --- /dev/null +++ b/java/src/juejin/lc/leetCode/RemoveElement.java @@ -0,0 +1,39 @@ +package juejin.lc.leetCode; + +/** + * 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 + * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 + * 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 + * @author liuchao + * @date 2019/5/24 + */ +public class RemoveElement { + /** + * 给定 nums = [3,2,2,3], val = 3, + * 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 + * @param nums + * @param val + * @return + */ + public int solution(int[]nums, int val){ + int index = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == val){ + ++index; + continue; + } + if (index > 0){ + nums[i - index] = nums[i]; + } + } + return nums.length - index; + } + + public static void main(String[] args) { + RemoveElement removeElement = new RemoveElement(); + int[] nums = {3,2,2,3}; + int val = 3; + int res = removeElement.solution(nums,val); + System.out.println(res); + } +} diff --git a/java/src/juejin/lc/leetCode/SearchInsert.java b/java/src/juejin/lc/leetCode/SearchInsert.java new file mode 100644 index 0000000..c37d2f8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/SearchInsert.java @@ -0,0 +1,48 @@ +package juejin.lc.leetCode; + +/** + * 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 + * 你可以假设数组中无重复元素。 + * + * @author liuchao + * @date 2019/5/24 + */ +public class SearchInsert { + /** + * [1,3,5,6], 5 2 + * [1,3,5,6], 2 1 + * [1,3,5,6], 7 4 + * [1,3,5,6], 0 0 + * + * @param nums 数组 + * @param target 目标 + * @return 返回位置 + */ + public int solution(int[] nums, int target) { + int prev = -1; + for (int i = 0; i < nums.length; i++) { + if (target > nums[i]) { + prev = nums[i]; + } else { + return i; + } + } + if (prev != -1){ + return nums.length; + } + return -1; + } + + public static void main(String[] args) { + SearchInsert searchInsert = new SearchInsert(); +// [1,3,5,6], 5 2 + int[] nums = {1,3,5,6}; + System.out.println(searchInsert.solution(nums,5)); +// [1,3,5,6], 2 1 + System.out.println(searchInsert.solution(nums,2)); +// [1,3,5,6], 7 4 + System.out.println(searchInsert.solution(nums,7)); +// [1,3,5,6], 0 0 + System.out.println(searchInsert.solution(nums,0)); + } +} diff --git a/java/src/juejin/lc/leetCode/StrStrSolution.java b/java/src/juejin/lc/leetCode/StrStrSolution.java new file mode 100644 index 0000000..4df25b3 --- /dev/null +++ b/java/src/juejin/lc/leetCode/StrStrSolution.java @@ -0,0 +1,45 @@ +package juejin.lc.leetCode; + +/** + * 给定一个 haystack 字符串和一个 needle 字符串, + * 在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。 + * 如果不存在,则返回 -1。 + * "" "" 0 + * "**" "" 0 + * "" "**" -1 + * @author liuchao + * @date 2019/5/24 + */ +public class StrStrSolution { + public int solution(String haystack, String needle) { + if ("".equals(needle) ||needle.equals(haystack)) { + return 0; + } + if ("".equals(haystack)) { + return -1; + } + int hlen = haystack.length(); + int nlen = needle.length(); + //hello ll + for (int i = 0; i <= hlen - nlen; i++) { + int j = 0; + for (; j < nlen; j++) { + System.out.println(haystack.charAt(i + j) + " -- " + needle.charAt(j)); + if (haystack.charAt(i + j) != needle.charAt(j)) { + break; + } + } + if (j == nlen) { + return i; + } + } + return -1; + } + + public static void main(String[] args) { + StrStrSolution strStrSolution = new StrStrSolution(); + String hasystack = "a"; + String needle = "a"; + System.out.println(strStrSolution.solution(hasystack,needle)); + } +} From 085e3247e0873087e260c41e875511debebb1411 Mon Sep 17 00:00:00 2001 From: liuchao Date: Mon, 27 May 2019 17:57:07 +0800 Subject: [PATCH 03/43] =?UTF-8?q?leetCode=20=E7=AE=80=E5=8D=95=E7=BA=A7?= =?UTF-8?q?=E5=88=AB=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=202019=E5=B9=B45?= =?UTF-8?q?=E6=9C=8827=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juejin/lc/leetCode/LengthOfLastWord.java | 56 +++++++++++++++++++ java/src/juejin/lc/leetCode/MaxSubArray.java | 42 ++++++++++++++ java/src/juejin/lc/leetCode/PlusOne.java | 54 ++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/LengthOfLastWord.java create mode 100644 java/src/juejin/lc/leetCode/MaxSubArray.java create mode 100644 java/src/juejin/lc/leetCode/PlusOne.java diff --git a/java/src/juejin/lc/leetCode/LengthOfLastWord.java b/java/src/juejin/lc/leetCode/LengthOfLastWord.java new file mode 100644 index 0000000..692a950 --- /dev/null +++ b/java/src/juejin/lc/leetCode/LengthOfLastWord.java @@ -0,0 +1,56 @@ +package juejin.lc.leetCode; + +/** + * 最后一个单词长度 + * + * @author liuchao + * @date 2019/5/27 + */ +public class LengthOfLastWord { + /** + * 给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。 + * 如果不存在最后一个单词,请返回 0 。 + * 说明:一个单词是指由字母组成,但不包含任何空格的字符串。 + * 输入: "Hello World" + * 输出: 5 + * + * @param s 单词 + * @return 长度 + */ + private int solution(String s) { + if (null == s || s.trim().length() == 0) { + return 0; + } + String[] strs = s.split(" "); + if (strs.length == 1) { + return s.trim().length(); + } + return strs[strs.length - 1].length(); + } + + /** + * 高效解法 + * + * @param s 单词 + * @return 长度 + */ + private int solution2(String s) { + int count = 0; + for (int i = s.length() - 1; i >= 0; i--) { + if (s.charAt(i) != ' ') { + ++count; + }else if (count != 0){ + return count; + } + } + return count; + } + + public static void main(String[] args) { + LengthOfLastWord lengthOfLastWord = new LengthOfLastWord(); + String s = "Hello World"; + System.out.println(lengthOfLastWord.solution(s)); + String s2 = " "; + System.out.println(lengthOfLastWord.solution2(s2)); + } +} diff --git a/java/src/juejin/lc/leetCode/MaxSubArray.java b/java/src/juejin/lc/leetCode/MaxSubArray.java new file mode 100644 index 0000000..8a22f4a --- /dev/null +++ b/java/src/juejin/lc/leetCode/MaxSubArray.java @@ -0,0 +1,42 @@ +package juejin.lc.leetCode; + +/** + * 最大子序列和 + * + * @author liuchao + * @date 2019/5/27 + */ +public class MaxSubArray { + /** + * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 + * 示例: + * 输入: [-2,1,-3,4,-1,2,1,-5,4], + * 输出: 6 + * 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 + * + * @param nums 数组 + * @return 和 + */ + private int solution(int[] nums) { + int sum = 0; + int res = nums[0]; + for (int num : nums) { + System.out.println("sum-before = " + sum + ",num = " + num + ",res-before = " + res); + //进行比较,sum存当前sum(n) + sum = sum > 0 ? sum + num : num; + System.out.println("sum-after = " + sum); + //res则对此次操作进行纠正 + if (res < sum) { + res = sum; + } + System.out.println("res-after = " + res); + } + return res; + } + + public static void main(String[] args) { + int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; + int res = new MaxSubArray().solution(nums); + System.out.println(res); + } +} diff --git a/java/src/juejin/lc/leetCode/PlusOne.java b/java/src/juejin/lc/leetCode/PlusOne.java new file mode 100644 index 0000000..4adae03 --- /dev/null +++ b/java/src/juejin/lc/leetCode/PlusOne.java @@ -0,0 +1,54 @@ +package juejin.lc.leetCode; + +/** + * 加一 + * + * @author liuchao + * @date 2019/5/27 + */ +public class PlusOne { + /** + * 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 + * 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。 + * 你可以假设除了整数 0 之外,这个整数不会以零开头。 + * + * @param digits 数组 + * @return 返回值 + */ + private int[] solution(int[] digits) { + // 5 + 1 = 6 常规 + // 9 + 1 = 10 末尾是9 需要整体向右平移一位 digits[0] = 1 + boolean flag = false; + for (int i = digits.length - 1; i >= 0; i--) { + if (digits[i] == 9) { + digits[i] = 0; + flag = true; + } else { + flag = false; + digits[i] += 1; + break; + } + } + // 9的情况,需要做数组右移操作 + int[] newDigits = null; + if (flag) { + newDigits = new int[digits.length + 1]; + newDigits[0] = 1; + for (int i = 0; i < digits.length; i++) { + newDigits[i + 1] = digits[i]; + } + }else{ + newDigits = digits; + } + return newDigits; + } + + + public static void main(String[] args) { + int[] digits = {8,9,9}; + int[] res = new PlusOne().solution(digits); + for (int i = 0; i < res.length; i++) { + System.out.print(res[i] + " "); + } + } +} From 08b42ac527b2b58f263722888c257f6ad53d070f Mon Sep 17 00:00:00 2001 From: liuchao Date: Tue, 28 May 2019 18:28:42 +0800 Subject: [PATCH 04/43] =?UTF-8?q?leetCode=20=E7=AE=80=E5=8D=95=E7=BA=A7?= =?UTF-8?q?=E5=88=AB=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=202019=E5=B9=B45=E6=9C=8828=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/AddBinary.java | 48 +++++++++ .../juejin/lc/leetCode/DeleteDuplicates.java | 53 ++++++++++ java/src/juejin/lc/leetCode/IsSameTree.java | 70 +++++++++++++ java/src/juejin/lc/leetCode/IsSymmetric.java | 53 ++++++++++ .../juejin/lc/leetCode/LevelOrderBottom.java | 98 +++++++++++++++++++ java/src/juejin/lc/leetCode/MaxDepth.java | 44 +++++++++ 6 files changed, 366 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/AddBinary.java create mode 100644 java/src/juejin/lc/leetCode/DeleteDuplicates.java create mode 100644 java/src/juejin/lc/leetCode/IsSameTree.java create mode 100644 java/src/juejin/lc/leetCode/IsSymmetric.java create mode 100644 java/src/juejin/lc/leetCode/LevelOrderBottom.java create mode 100644 java/src/juejin/lc/leetCode/MaxDepth.java diff --git a/java/src/juejin/lc/leetCode/AddBinary.java b/java/src/juejin/lc/leetCode/AddBinary.java new file mode 100644 index 0000000..6692282 --- /dev/null +++ b/java/src/juejin/lc/leetCode/AddBinary.java @@ -0,0 +1,48 @@ +package juejin.lc.leetCode; + +/** + * 二进制求和 + * + * @author liuchao + * @date 2019/5/27 + */ +public class AddBinary { + /** + * 给定两个二进制字符串,返回他们的和(用二进制表示)。 + * 输入为非空字符串且只包含数字 1 和 0。 + * 示例 1: + * 输入: a = "11", b = "1" + * 输出: "100" + * 示例 2: + * 输入: a = "1010", b = "1011" + * 输出: "10101" + * + * @param a 二进制数字 + * @param b 二进制数字 + * @return 返回结果 + */ + public String solution(String a, String b) { + int al = a.length() - 1; + int bl = b.length() - 1; + StringBuilder stringBuilder = new StringBuilder(); + int carry = 0; + while (al >= 0 || bl >= 0 || carry == 1) { + if (al >= 0 && a.charAt(al--) == '1') { + ++carry; + } + if (bl >= 0 && b.charAt(bl--) == '1') { + ++carry; + } + stringBuilder.append(carry % 2); + carry /= 2; + } + return stringBuilder.reverse().toString(); + } + + public static void main(String[] args) { + AddBinary addBinary = new AddBinary(); + String a = "1010"; + String b = "1011"; + System.out.println(addBinary.solution(a,b)); + } +} diff --git a/java/src/juejin/lc/leetCode/DeleteDuplicates.java b/java/src/juejin/lc/leetCode/DeleteDuplicates.java new file mode 100644 index 0000000..89afb35 --- /dev/null +++ b/java/src/juejin/lc/leetCode/DeleteDuplicates.java @@ -0,0 +1,53 @@ +package juejin.lc.leetCode; + +/** + * 删除排序链表中的重复元素 + * + * @author liuchao + * @date 2019/5/28 + */ +public class DeleteDuplicates { + /** + * 输入: 1->1->2 + * 输出: 1->2 + * 输入: 1->1->2->3->3 + * 输出: 1->2->3 + * + * @param head 链表 + * @return 返回新链表 + */ + public ListNode solution(ListNode head) { + ListNode p = head; + while (null != p && null != p.next) { + if (p.val == p.next.val){ + p.next = p.next.next; + }else{ + p = p.next; + } + } + return head; + } + + private static class ListNode { + int val; + ListNode next; + + ListNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + DeleteDuplicates deleteDuplicates = new DeleteDuplicates(); + ListNode head = new ListNode(1); + head.next = new ListNode(1); + head.next.next = new ListNode(2); + head.next.next.next = new ListNode(3); + head.next.next.next.next = new ListNode(3); + ListNode res = deleteDuplicates.solution(head); + while (null != res){ + System.out.print(res.val + " "); + res = res.next; + } + } +} diff --git a/java/src/juejin/lc/leetCode/IsSameTree.java b/java/src/juejin/lc/leetCode/IsSameTree.java new file mode 100644 index 0000000..64103fb --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsSameTree.java @@ -0,0 +1,70 @@ +package juejin.lc.leetCode; + +import javax.swing.tree.TreeNode; + +/** + * 相同的树 + * + * @author liuchao + * @date 2019/5/28 + */ +public class IsSameTree { + + /** + * 给定两个二叉树,编写一个函数来检验它们是否相同。 + * 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 + * 示例 1: + * 输入: 1 1 + * / \ / \ + * 2 3 2 3 + * [1,2,3], [1,2,3] + * 输出: true + * 示例 2: + * 输入: 1 1 + * / \ + * 2 2 + * [1,2], [1,null,2] + * 输出: false + * 示例 3: + * 输入: 1 1 + * / \ / \ + * 2 1 1 2 + * [1,2,1], [1,1,2] + * 输出: false + * + * @param p 二叉树p + * @param q 二叉树q + * @return 返回结果 + */ + private boolean solution(TreeNode p, TreeNode q) { + if (null == p && q == null) { + return true; + } + if (null != p && null != q && p.val == q.val) { + return solution(p.left, q.left) && solution(p.right, q.right); + } + return false; + } + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + IsSameTree isSameTree = new IsSameTree(); + TreeNode p = new TreeNode(0); + p.left = new TreeNode(-5); +// p.right = new TreeNode(3); + TreeNode q = new TreeNode(0); +// q.left = null; + q.left = new TreeNode(-8); +// q.right = new TreeNode(3); + System.out.println(isSameTree.solution(p, q)); + } +} diff --git a/java/src/juejin/lc/leetCode/IsSymmetric.java b/java/src/juejin/lc/leetCode/IsSymmetric.java new file mode 100644 index 0000000..5c9e016 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsSymmetric.java @@ -0,0 +1,53 @@ +package juejin.lc.leetCode; + +import javax.swing.tree.TreeNode; + +/** + * 对称二叉树 + * + * @author liuchao + * @date 2019/5/28 + */ +public class IsSymmetric { + /** + *例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 + * 1 + * / \ + * 2 2 + * / \ / \ + * 3 4 4 3 + * 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: + * 1 + * / \ + * 2 2 + * \ \ + * 3 3 + * @param root 二叉树 + * @return 返回结果 + */ + private boolean solution(TreeNode root) { + if (null == root){ + return true; + } + return traversal(root.left,root.right); + } + private boolean traversal(TreeNode left,TreeNode right){ + if (null == left && right == null){ + return true; + } + if (null != left && null != right && left.val == right.val){ + return traversal(left.left,right.right) && traversal(left.right,right.left); + } + return false; + } + + private class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } +} diff --git a/java/src/juejin/lc/leetCode/LevelOrderBottom.java b/java/src/juejin/lc/leetCode/LevelOrderBottom.java new file mode 100644 index 0000000..c4cdf34 --- /dev/null +++ b/java/src/juejin/lc/leetCode/LevelOrderBottom.java @@ -0,0 +1,98 @@ +package juejin.lc.leetCode; + +import javax.swing.tree.TreeNode; +import java.util.*; + +/** + * 按层遍历 + * 自下向上输出 + * + * @author liuchao + * @date 2019/5/28 + */ +public class LevelOrderBottom { + /** + * 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) + * 例如: + * 给定二叉树 [3,9,20,null,null,15,7], + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * 返回其自底向上的层次遍历为: + * [ + * [15,7], + * [9,20], + * [3] + * ] + * + * @param root 二叉树 + * @return 集合 + */ + public List> solution(TreeNode root) { + if (null == root) { + return new ArrayList<>(); + } + List> lists = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + List list = new ArrayList<>(); + int size = queue.size(); + for (int i = 0; i < size; i++) { + TreeNode node = queue.poll(); + if (null != node) { + list.add(node.val); + if (null != node.left) { + queue.offer(node.left); + } + if (null != node.right) { + queue.offer(node.right); + } + } + } + lists.add(list); + } + Collections.reverse(lists); + return lists; + } + + private void traversal(TreeNode root) { + if (null == root) return; + System.out.print(root.val + " "); + traversal(root.right); + traversal(root.left); + } + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + TreeNode root = new TreeNode(3); + root.left = new TreeNode(9); + root.right = new TreeNode(20); + root.left.left = null; + root.left.right = new TreeNode(15); + root.right.left = null; + root.right.right = new TreeNode(7); + LevelOrderBottom levelOrderBottom = new LevelOrderBottom(); + //将其输出反转就是常规二叉树的自下向上输出 +// levelOrderBottom.traversal(root); + List> lists = levelOrderBottom.solution(root); + for (List list : lists) { + System.out.print("["); + for (Integer i : list) { + System.out.print(i + " "); + } + System.out.println("]"); + } + } +} diff --git a/java/src/juejin/lc/leetCode/MaxDepth.java b/java/src/juejin/lc/leetCode/MaxDepth.java new file mode 100644 index 0000000..b9c6fd8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/MaxDepth.java @@ -0,0 +1,44 @@ +package juejin.lc.leetCode; + +import java.util.LinkedList; + +/** + * 二叉树的最大深度 + * + * @author liuchao + * @date 2019/5/28 + */ +public class MaxDepth { + private int solution(TreeNode root) { + if (root == null) { + return 0; + } else { + int ll = solution(root.left); + int rl = solution(root.right); + return Math.max(ll, rl) + 1; + } + } + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + MaxDepth maxDepth = new MaxDepth(); + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.left.left = new TreeNode(4); + root.left.right = null; + root.right.left = null; + root.right.right = new TreeNode(5); + int depth = maxDepth.solution(root); + System.out.println(depth); + } +} From 6ffa768e6af6c5400db273c2278fa0989cf2fb3b Mon Sep 17 00:00:00 2001 From: liuchao Date: Mon, 3 Jun 2019 11:30:52 +0800 Subject: [PATCH 05/43] =?UTF-8?q?leetCode=20=E7=AE=80=E5=8D=95=E7=BA=A7?= =?UTF-8?q?=E5=88=AB=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=202019=E5=B9=B45=E6=9C=8830=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juejin/lc/leetCode/GenerateSolution.java | 77 +++++++++++++++++++ java/src/juejin/lc/leetCode/HasPathSum.java | 44 +++++++++++ java/src/juejin/lc/leetCode/IsBalanced.java | 74 ++++++++++++++++++ java/src/juejin/lc/leetCode/MaxDepth.java | 8 +- java/src/juejin/lc/leetCode/MaxProfit.java | 73 ++++++++++++++++++ java/src/juejin/lc/leetCode/MinDepth.java | 41 ++++++++++ .../juejin/lc/leetCode/SortedArrayToBST.java | 64 +++++++++++++++ 7 files changed, 375 insertions(+), 6 deletions(-) create mode 100644 java/src/juejin/lc/leetCode/GenerateSolution.java create mode 100644 java/src/juejin/lc/leetCode/HasPathSum.java create mode 100644 java/src/juejin/lc/leetCode/IsBalanced.java create mode 100644 java/src/juejin/lc/leetCode/MaxProfit.java create mode 100644 java/src/juejin/lc/leetCode/MinDepth.java create mode 100644 java/src/juejin/lc/leetCode/SortedArrayToBST.java diff --git a/java/src/juejin/lc/leetCode/GenerateSolution.java b/java/src/juejin/lc/leetCode/GenerateSolution.java new file mode 100644 index 0000000..31befa3 --- /dev/null +++ b/java/src/juejin/lc/leetCode/GenerateSolution.java @@ -0,0 +1,77 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.List; + +/** + * 杨辉三角 + * + * @author liuchao + * @date 2019/5/29 + */ +public class GenerateSolution { + /** + * 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。 + * 在杨辉三角中,每个数是它左上方和右上方的数的和。 + * 示例: + * 输入: 5 + * 输出: + * [ + * [1], + * [1,1], + * [1,2,1], + * [1,3,3,1], + * [1,4,6,4,1] + * ] + * + * @param numRows 整数 + * @return 返回结果 + */ + public List> generate(int numRows) { + List> triangle = new ArrayList<>(); + if (numRows == 0) { + return triangle; + } + //numRows = 1 特殊处理 + triangle.add(new ArrayList<>()); + triangle.get(0).add(1); + for (int rowNum = 1; rowNum < numRows; rowNum++) { + List row = new ArrayList<>(); + List perRow = triangle.get(rowNum - 1); + row.add(1); + for (int i = 1; i < rowNum; i++) { + row.add(perRow.get(i - 1) + perRow.get(i)); + } + row.add(1); + triangle.add(row); + } + return triangle; + } + + /** + * 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。 + * 在杨辉三角中,每个数是它左上方和右上方的数的和。 + * 示例: + * 输入: 3 + * 输出: [1,3,3,1] + * + * @param rowIndex + * @return + */ + public List getRow(int rowIndex) { + // * 获取杨辉三角的指定行 + // * 直接使用组合公式C(n,i) = n!/(i!*(n-i)!) + // * 则第(i+1)项是第i项的倍数=(n-i)/(i+1); + List res = new ArrayList<>(rowIndex + 1); + long cur = 1; + for (int i = 0; i <= rowIndex; i++) { + res.add((int) cur); + cur = cur * (rowIndex - i) / (i + 1); + } + return res; + } + + public static void main(String[] args) { + + } +} diff --git a/java/src/juejin/lc/leetCode/HasPathSum.java b/java/src/juejin/lc/leetCode/HasPathSum.java new file mode 100644 index 0000000..4848652 --- /dev/null +++ b/java/src/juejin/lc/leetCode/HasPathSum.java @@ -0,0 +1,44 @@ +package juejin.lc.leetCode; + +/** + * 路径总和 + * @author liuchao + * @date 2019/5/29 + */ +public class HasPathSum { + /** + * 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 + * 说明: 叶子节点是指没有子节点的节点。 + * 示例: + * 给定如下二叉树,以及目标和 sum = 22, + * 5 + * / \ + * 4 8 + * / / \ + * 11 13 4 + * / \ \ + * 7 2 1 + * 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。 + * @param root 二叉树 + * @param sum 路径总和 + * @return 返回结果 + */ + public boolean solution(TreeNode root, int sum) { + if (null == root){ + return false; + } + if (null == root.left && null == root.right){ + return sum - root.val == 0; + } + return solution(root.left,sum - root.val) || solution(root.right,sum - root.val); + } + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } +} diff --git a/java/src/juejin/lc/leetCode/IsBalanced.java b/java/src/juejin/lc/leetCode/IsBalanced.java new file mode 100644 index 0000000..70a9802 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsBalanced.java @@ -0,0 +1,74 @@ +package juejin.lc.leetCode; + +import javax.swing.tree.TreeNode; + +/** + * 判断一个二叉树是否平衡 + * + * @author liuchao + * @date 2019/5/29 + */ +public class IsBalanced { + /** + * 给定一个二叉树,判断它是否是高度平衡的二叉树。 + * 本题中,一棵高度平衡二叉树定义为: + * 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 + * 示例 1: + * 给定二叉树 [3,9,20,null,null,15,7] + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * 返回 true + * 示例 2: + * 给定二叉树 [1,2,2,3,3,null,null,4,4] + * 1 + * / \ + * 2 2 + * / \ + * 3 3 + * / \ + * 4 4 + * 返回 false + * + * @param root 二叉树 + * @return 返回结果 + */ + private boolean solution(TreeNode root) { + if (null == root) { + return true; + } + return (Math.abs(depth(root.left) - depth(root.right)) <= 1) && solution(root.left) && solution(root.right); + } + + private int depth(TreeNode root) { + //递归出口 + if (null == root) { + return 0; + } + return Math.max(depth(root.left), depth(root.right)) + 1; + } + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + IsBalanced isBalanced = new IsBalanced(); +// [1,null,2,null,3] + TreeNode node = new TreeNode(1); + node.left = null; + node.right = new TreeNode(2); + node.right.left = null; + node.right.right = new TreeNode(3); + boolean bool = isBalanced.solution(node); + System.out.println(bool); + } +} diff --git a/java/src/juejin/lc/leetCode/MaxDepth.java b/java/src/juejin/lc/leetCode/MaxDepth.java index b9c6fd8..3a75422 100644 --- a/java/src/juejin/lc/leetCode/MaxDepth.java +++ b/java/src/juejin/lc/leetCode/MaxDepth.java @@ -1,7 +1,5 @@ package juejin.lc.leetCode; -import java.util.LinkedList; - /** * 二叉树的最大深度 * @@ -10,12 +8,10 @@ */ public class MaxDepth { private int solution(TreeNode root) { - if (root == null) { + if (null == root) { return 0; } else { - int ll = solution(root.left); - int rl = solution(root.right); - return Math.max(ll, rl) + 1; + return Math.max(solution(root.left), solution(root.right)) + 1; } } diff --git a/java/src/juejin/lc/leetCode/MaxProfit.java b/java/src/juejin/lc/leetCode/MaxProfit.java new file mode 100644 index 0000000..64e472f --- /dev/null +++ b/java/src/juejin/lc/leetCode/MaxProfit.java @@ -0,0 +1,73 @@ +package juejin.lc.leetCode; + +/** + * 买入股票的最佳时机 + * + * @author liuchao + * @date 2019/5/29 + */ +public class MaxProfit { + /** + * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 + * 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。 + * 注意你不能在买入股票前卖出股票。 + * 示例 1: + * 输入: [7,1,5,3,6,4] + * 输出: 5 + * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 + * 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。 + * 示例 2: + * 输入: [7,6,4,3,1] + * 输出: 0 + * 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 + * + * @param prices 价格数组 + * @return 利润 + */ + public int solution(int[] prices) { +// 动态规划 前i天的最大收益 = max{前i-1天的最大收益,第i天的价格-前i-1天中的最小价格} + if (null == prices || prices.length < 2) { + return 0; + } + int minProfit = prices[0]; + int maxProfit = 0; + + for (int i = 1; i < prices.length; i++) { + maxProfit = Math.max(maxProfit, prices[i] - minProfit); + minProfit = Math.min(minProfit, prices[i]); + } + return maxProfit; + } + + /** + * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 + * 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 + * 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 + * 示例 1: + * 输入: [7,1,5,3,6,4] + * 输出: 7 + * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 + * 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 + * 示例 2: + * 输入: [1,2,3,4,5] + * 输出: 4 + * 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 + * 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。 + * 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 + * 示例 3: + * 输入: [7,6,4,3,1] + * 输出: 0 + * 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 + * @param prices 价格数组 + * @return 返回值 + */ + public int solution2(int[] prices){ + return 0; + } + public static void main(String[] args) { + int[] prices = {2, 4, 1}; + MaxProfit maxProfit = new MaxProfit(); + int res = maxProfit.solution(prices); + System.out.println(res); + } +} diff --git a/java/src/juejin/lc/leetCode/MinDepth.java b/java/src/juejin/lc/leetCode/MinDepth.java new file mode 100644 index 0000000..f0119c8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/MinDepth.java @@ -0,0 +1,41 @@ +package juejin.lc.leetCode; + + +/** + * 二叉树的最小深度 + * + * @author liuchao + * @date 2019/5/29 + */ +public class MinDepth { + /** + * + * @param root 二叉树 + * @return 最小深度 + */ + private int solution(TreeNode root) { + if (null == root) { + return 0; + } + int left = solution(root.left); + int right = solution(root.right); + if (left == 0) { + return right + 1; + } + if (right == 0) { + return left + 1; + } + return Math.min(left, right) + 1; + } + + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } +} diff --git a/java/src/juejin/lc/leetCode/SortedArrayToBST.java b/java/src/juejin/lc/leetCode/SortedArrayToBST.java new file mode 100644 index 0000000..728a622 --- /dev/null +++ b/java/src/juejin/lc/leetCode/SortedArrayToBST.java @@ -0,0 +1,64 @@ +package juejin.lc.leetCode; + + +/** + * 将有序数组转化为二叉搜索树 + * + * @author liuchao + * @date 2019/5/29 + */ +public class SortedArrayToBST { + /** + * 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。 + * 示例: + * 给定有序数组: [-10,-3,0,5,9], + * 一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树: + * 0 + * / \ + * -3 9 + * / / + * -10 5 + * + * @param nums 有序数组 + * @return 二叉搜索树 + */ + private TreeNode solution(int[] nums) { + // 左右等分建立左右子树,中间节点作为子树根节点,递归该过程 + return nums == null ? null : buildTree(nums, 0, nums.length - 1); + } + + private TreeNode buildTree(int[] nums, int low, int high) { + if (low > high) { + return null; + } + int mid = low + ((high - low) >> 1); + TreeNode node = new TreeNode(nums[mid]); + node.left = buildTree(nums, low, mid - 1); + node.right = buildTree(nums, mid + 1, high); + return node; + } + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + private void inOrderTraversal(TreeNode node){ + if (null == node){ + return; + } + System.out.print(node.val + " "); + inOrderTraversal(node.left); + inOrderTraversal(node.right); + } + public static void main(String[] args) { + SortedArrayToBST sortedArrayToBST = new SortedArrayToBST(); + int[] nums = {-10, -3, 0, 5, 9}; + TreeNode node = sortedArrayToBST.solution(nums); + sortedArrayToBST.inOrderTraversal(node); + } +} From 94d15a9558da526b9e19ebe7b90eb42fb23edab1 Mon Sep 17 00:00:00 2001 From: liuchao Date: Thu, 6 Jun 2019 19:29:53 +0800 Subject: [PATCH 06/43] =?UTF-8?q?leetCode=20=E7=AE=80=E5=8D=95=E7=BA=A7?= =?UTF-8?q?=E5=88=AB=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=202019=E5=B9=B46=E6=9C=886=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lc/leetCode/IsPalindromeSolution.java | 53 +++++++++++++++++++ java/src/juejin/lc/leetCode/MaxProfit.java | 24 ++++++--- 2 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 java/src/juejin/lc/leetCode/IsPalindromeSolution.java diff --git a/java/src/juejin/lc/leetCode/IsPalindromeSolution.java b/java/src/juejin/lc/leetCode/IsPalindromeSolution.java new file mode 100644 index 0000000..5595405 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsPalindromeSolution.java @@ -0,0 +1,53 @@ +package juejin.lc.leetCode; + +/** + * 验证回文串 + * + * @author liuchao + * @date 2019/6/6 + */ +public class IsPalindromeSolution { + /** + * 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 + * 说明:本题中,我们将空字符串定义为有效的回文串。 + * 示例 1: + * 输入: "A man, a plan, a canal: Panama" + * 输出: true + * 示例 2: + * 输入: "race a car" + * 输出: false + * + * @param s 输入字符串 + * @return 返回结果 + */ + private boolean solution(String s) { + if (null == s) { + return false; + } + s = s.toLowerCase(); + int i = 0; + int j = s.length() - 1; + while (i < j) { + while (i < j && !Character.isLetterOrDigit(s.charAt(i))) { + ++i; + } + while (i < j && !Character.isLetterOrDigit(s.charAt(j))) { + --j; + } + if (s.charAt(i) != s.charAt(j)) { + return false; + } + ++i; + --j; + } + return true; + } + + public static void main(String[] args) { + IsPalindromeSolution isPalindromeSolution = new IsPalindromeSolution(); +// String s = "A man, a plan, a canal: Panama"; +// System.out.println(isPalindromeSolution.solution(s)); + String s1 = "race a car"; + System.out.println(isPalindromeSolution.solution(s1)); + } +} diff --git a/java/src/juejin/lc/leetCode/MaxProfit.java b/java/src/juejin/lc/leetCode/MaxProfit.java index 64e472f..03242a7 100644 --- a/java/src/juejin/lc/leetCode/MaxProfit.java +++ b/java/src/juejin/lc/leetCode/MaxProfit.java @@ -47,27 +47,37 @@ public int solution(int[] prices) { * 输入: [7,1,5,3,6,4] * 输出: 7 * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 - * 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 + * 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 * 示例 2: * 输入: [1,2,3,4,5] * 输出: 4 * 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 - * 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。 - * 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 + * 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。 + * 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 * 示例 3: * 输入: [7,6,4,3,1] * 输出: 0 * 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 + * * @param prices 价格数组 * @return 返回值 */ - public int solution2(int[] prices){ - return 0; + private int solution2(int[] prices) { + int maxProfit = 0; + for (int i = 1; i < prices.length; i++) { + if (prices[i] - prices[i - 1] > 0){ + maxProfit += prices[i] - prices[i - 1]; + } + System.out.println("prices[i] - prices[i - 1] = " + (prices[i] - prices[i - 1])); + } + return maxProfit; } + public static void main(String[] args) { - int[] prices = {2, 4, 1}; + int[] prices = {1,2,3,4,5}; +// int[] prices = {7, 1, 5, 3, 6, 4}; MaxProfit maxProfit = new MaxProfit(); - int res = maxProfit.solution(prices); + int res = maxProfit.solution2(prices); System.out.println(res); } } From a517992f8829501f6e7f0869a5d5d0056b850f5f Mon Sep 17 00:00:00 2001 From: liuchao Date: Tue, 18 Jun 2019 17:11:39 +0800 Subject: [PATCH 07/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0=202019=E5=B9=B46=E6=9C=8818=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juejin/lc/leetCode/ConvertToTitle.java | 55 +++++++++++++ .../lc/leetCode/GetIntersectionNode.java | 55 +++++++++++++ java/src/juejin/lc/leetCode/HasCycle.java | 55 +++++++++++++ .../juejin/lc/leetCode/MajorityElement.java | 65 +++++++++++++++ java/src/juejin/lc/leetCode/MinStack.java | 81 +++++++++++++++++++ java/src/juejin/lc/leetCode/SingleNumber.java | 37 +++++++++ java/src/juejin/lc/leetCode/TwoSum.java | 56 +++++++++++++ 7 files changed, 404 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/ConvertToTitle.java create mode 100644 java/src/juejin/lc/leetCode/GetIntersectionNode.java create mode 100644 java/src/juejin/lc/leetCode/HasCycle.java create mode 100644 java/src/juejin/lc/leetCode/MajorityElement.java create mode 100644 java/src/juejin/lc/leetCode/MinStack.java create mode 100644 java/src/juejin/lc/leetCode/SingleNumber.java create mode 100644 java/src/juejin/lc/leetCode/TwoSum.java diff --git a/java/src/juejin/lc/leetCode/ConvertToTitle.java b/java/src/juejin/lc/leetCode/ConvertToTitle.java new file mode 100644 index 0000000..3a9cc94 --- /dev/null +++ b/java/src/juejin/lc/leetCode/ConvertToTitle.java @@ -0,0 +1,55 @@ +package juejin.lc.leetCode; + +/** + * Excel表列名称 + * + * @author liuchao + * @date 2019/6/18 + */ +public class ConvertToTitle { + /** + * 给定一个正整数,返回它在 Excel 表中相对应的列名称。 + * 例如, + * 1 -> A + * 2 -> B + * 3 -> C + * ... + * 26 -> Z + * 27 -> AA + * 28 -> AB + * ... + * 示例 1: + * 输入: 1 + * 输出: "A" + * 示例 2: + * 输入: 28 + * 输出: "AB" + * 示例 3: + * 输入: 701 + * 输出: "ZY" + * + * @param n line + * @return row + */ + private String solution(int n) { + if (n <= 0) { + return ""; + } + StringBuilder stringBuilder = new StringBuilder(); + while (n > 0) { + --n; + System.out.println(n + " % 26 = " + (char) (n % 26 + 'A')); + stringBuilder.append((char) (n % 26 + 'A')); + System.out.println(n + " / 26 = " + (n / 26)); + n /= 26; + } + return stringBuilder.reverse().toString(); + } + + public static void main(String[] args) { + ConvertToTitle convertToTitle = new ConvertToTitle(); + int n = 703; + String str = convertToTitle.solution(n); + System.out.println("result:" + str); + } +} diff --git a/java/src/juejin/lc/leetCode/GetIntersectionNode.java b/java/src/juejin/lc/leetCode/GetIntersectionNode.java new file mode 100644 index 0000000..fad06ff --- /dev/null +++ b/java/src/juejin/lc/leetCode/GetIntersectionNode.java @@ -0,0 +1,55 @@ +package juejin.lc.leetCode; + +/** + * 相交链表 + * + * @author liuchao + * @date 2019/6/18 + */ +public class GetIntersectionNode { + public ListNode solution(ListNode headA, ListNode headB) { + if (headA == null || headB == null) { + return null; + } + // 定义两个指针, 第一轮让两个到达末尾的节点指向另一个链表的头部, 最后如果相遇则为交点(在第一轮移动中恰好抹除了长度差) + // 两个指针等于移动了相同的距离, 有交点就返回, 无交点就是各走了两条指针的长度 + ListNode pA = headA, pB = headB; + // 在这里第一轮体现在pA和pB第一次到达尾部会移向另一链表的表头, + // 而第二轮体现在如果pA或pB相交就返回交点, 不相交最后就是null==null + while (pA != pB) { + pA = null == pA ? headB : pA.next; + pB = null == pB ? headA : pB.next; + } + return pA; + } + + private static class ListNode { + int val; + ListNode next; + + ListNode(int x) { + val = x; + next = null; + } + } + + public static void main(String[] args) { + //4 1 8 4 5 + ListNode headA = new ListNode(4); + headA.next = new ListNode(1); + headA.next.next = new ListNode(8); + headA.next.next.next = new ListNode(4); + headA.next.next.next.next = new ListNode(5); + //5 0 1 8 4 5 + ListNode headB = new ListNode(5); + headB.next = new ListNode(0); + headB.next.next = new ListNode(1); + headB.next.next.next = new ListNode(8); + headB.next.next.next.next = new ListNode(4); + headB.next.next.next.next.next = new ListNode(5); + GetIntersectionNode getIntersectionNode = new GetIntersectionNode(); + ListNode resNode = getIntersectionNode.solution(headA, headB); + System.out.println(null == resNode); + + } +} diff --git a/java/src/juejin/lc/leetCode/HasCycle.java b/java/src/juejin/lc/leetCode/HasCycle.java new file mode 100644 index 0000000..878af08 --- /dev/null +++ b/java/src/juejin/lc/leetCode/HasCycle.java @@ -0,0 +1,55 @@ +package juejin.lc.leetCode; + +/** + * 环形链表 + * + * @author liuchao + * @date 2019/6/10 + */ +public class HasCycle { + /** + * 给定一个链表,判断链表中是否有环。 + * 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 + * 示例 1: + * 输入:head = [3,2,0,-4], pos = 1 + * 输出:true + * 解释:链表中有一个环,其尾部连接到第二个节点。 + * 示例 2: + * 输入:head = [1,2], pos = 0 + * 输出:true + * 解释:链表中有一个环,其尾部连接到第一个节点。 + * 示例 3: + * 输入:head = [1], pos = -1 + * 输出:false + * 解释:链表中没有环。 + * 进阶: + * 你能用 O(1)(即,常量)内存解决此问题吗? + * + * @param head 链表 + * @return 返回值 + */ + private boolean solution(ListNode head) { + if (null == head || null == head.next){ + return false; + } + ListNode slow = head; + ListNode fast = head.next; + while (null != fast && null != fast.next){ + slow = slow.next; + fast = fast.next.next; + if (slow == fast){ + return true; + } + } + return false; + } + + private class ListNode { + int val; + ListNode next; + ListNode(int x) { + val = x; + next = null; + } + } +} diff --git a/java/src/juejin/lc/leetCode/MajorityElement.java b/java/src/juejin/lc/leetCode/MajorityElement.java new file mode 100644 index 0000000..45b2b2c --- /dev/null +++ b/java/src/juejin/lc/leetCode/MajorityElement.java @@ -0,0 +1,65 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * 求众数 + * + * @author liuchao + * @date 2019/6/18 + */ +public class MajorityElement { + /** + * 给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 + * 你可以假设数组是非空的,并且给定的数组总是存在众数。 + * 示例 1: + * 输入: [3,2,3] + * 输出: 3 + * 示例 2: + * 输入: [2,2,1,1,1,2,2] + * 输出: 2 + * + * @param nums 数组 + * @return 众数 + */ + public int solution(int[] nums) { + //摩根投票法 + int ret = nums[0]; + System.out.println("nums[0] = " + ret); + int count = 1; + for(int num : nums) { + System.out.println("num = " + num + ", ret = " + ret + ", count = " + count); + if(num != ret) { + count--; + if(count == 0) { + count = 1; + ret = num; + } + } + else{ + count++; + } + } + return ret; + } + + /** + * 最优解 + * + * @param nums 数组 + * @return 反转后取中间值 + */ + public int solutiont(int[] nums) { + Arrays.sort(nums); + return nums[nums.length / 2]; + } + + public static void main(String[] args) { + MajorityElement majorityElement = new MajorityElement(); + int[] nums = {3,2,3,1,5,1,4,1,1}; + int res = majorityElement.solution(nums); + System.out.println(res); + } +} diff --git a/java/src/juejin/lc/leetCode/MinStack.java b/java/src/juejin/lc/leetCode/MinStack.java new file mode 100644 index 0000000..7894a9f --- /dev/null +++ b/java/src/juejin/lc/leetCode/MinStack.java @@ -0,0 +1,81 @@ +package juejin.lc.leetCode; + +import java.util.Stack; + +/** + * 最小栈 + * + * @author liuchao + * @date 2019/6/10 + */ +public class MinStack { + private Stack stack; + + /** + * 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。 + * push(x) -- 将元素 x 推入栈中。 + * pop() -- 删除栈顶的元素。 + * top() -- 获取栈顶元素。 + * getMin() -- 检索栈中的最小元素。 + * 示例: + * MinStack minStack = new MinStack(); + * minStack.push(-2); + * minStack.push(0); + * minStack.push(-3); + * minStack.getMin(); --> 返回 -3. + * minStack.pop(); + * minStack.top(); --> 返回 0. + * minStack.getMin(); --> 返回 -2. + */ + public MinStack() { + stack = new Stack<>(); + } + + public void push(int x) { + if (stack.isEmpty()) { + stack.push(x); + stack.push(x); + } else { + int min = stack.peek(); + stack.push(x); + if (min < x) { + stack.push(min); + } else { + stack.push(x); + } + } + } + + public void pop() { + stack.pop(); + stack.pop(); + } + + public int top() { + System.out.println("size=" + stack.size()); + return stack.get(stack.size() - 2); + } + + public int getMin() { + return stack.peek(); + } + + public static void main(String[] args) { + MinStack minStack = new MinStack(); + minStack.push(-2); + minStack.push(0); + minStack.push(-3); +// while (!minStack.stack.isEmpty()){ +// System.out.println("" + minStack.stack.pop()); +// } +// System.out.println("----------------------"); +// System.out.println("length= " + minStack.stack.size()); + int min = minStack.getMin(); + System.out.println("最小值:" + min); + minStack.pop(); + int top = minStack.top(); + System.out.println("top:" + top); + int newMin = minStack.getMin(); + System.out.println("newMin:" + newMin); + } +} diff --git a/java/src/juejin/lc/leetCode/SingleNumber.java b/java/src/juejin/lc/leetCode/SingleNumber.java new file mode 100644 index 0000000..afac40c --- /dev/null +++ b/java/src/juejin/lc/leetCode/SingleNumber.java @@ -0,0 +1,37 @@ +package juejin.lc.leetCode; + +/** + * 只出现一次的数字 + * + * @author liuchao + * @date 2019/6/6 + */ +public class SingleNumber { + /** + * 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 + * 示例 1: + * 输入: [2,2,1] + * 输出: 1 + * 示例 2: + * 输入: [4,1,2,1,2] + * 输出: 4 + * + * @param nums 数组 + * @return 返回结果 + */ + public int solution(int[] nums) { + //思路:异或:相同为0,不同为1. 异或同一个数两次,原数不变。 + int len = nums.length; + int result = 0; + for (int i = 0; i < len; i++) { + result ^= nums[i]; + } + return result; + } + + public static void main(String[] args) { + SingleNumber singleNumber = new SingleNumber(); + int[] nums = {4, 1, 2, 1, 2}; + singleNumber.solution(nums); + } +} diff --git a/java/src/juejin/lc/leetCode/TwoSum.java b/java/src/juejin/lc/leetCode/TwoSum.java new file mode 100644 index 0000000..564e766 --- /dev/null +++ b/java/src/juejin/lc/leetCode/TwoSum.java @@ -0,0 +1,56 @@ +package juejin.lc.leetCode; + +import java.util.*; + +/** + * 两数之和 + * + * @author liuchao + * @date 2019/6/18 + */ +public class TwoSum { + /** + * 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 + * 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。 + * 说明: + * 返回的下标值(index1 和 index2)不是从零开始的。 + * 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 + * 示例: + * 输入: numbers = [2, 7, 11, 15], target = 9 + * 输出: [1,2] + * 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 + * + * @param numbers 数组 + * @param target 目标值 + * @return 返回数组 + */ + public int[] solution(int[] numbers, int target) { + int[] result = new int[2]; + int i = 0; + int j = numbers.length - 1; + while (i < j) { + if (numbers[i] + numbers[j] == target) { + result[0] = i + 1; + result[1] = j + 1; + break; + } else { + if (numbers[i] + numbers[j] < target) { + ++i; + } else { + --j; + } + } + } + return result; + } + + public static void main(String[] args) { + TwoSum twoSum = new TwoSum(); + int[] numbers = {12, 13, 23, 28, 43, 44, 59, 60, 61, 68, 70, 86, 88, 92, 124, 125, 136, 168, 173, 173, 180, 199, 212, 221, 227, 230, 277, 282, 306, 314, 316, 321, 325, 328, 336, 337, 363, 365, 368, 370, 370, 371, 375, 384, 387, 394, 400, 404, 414, 422, 422, 427, 430, 435, 457, 493, 506, 527, 531, 538, 541, 546, 568, 583, 585, 587, 650, 652, 677, 691, 730, 737, 740, 751, 755, 764, 778, 783, 785, 789, 794, 803, 809, 815, 847, 858, 863, 863, 874, 887, 896, 916, 920, 926, 927, 930, 933, 957, 981, 997}; + int target = 542; + int[] result = twoSum.solution(numbers, target); + for (int i = 0; i < result.length; i++) { + System.out.print(result[i] + " "); + } + } +} From c4219ceb530ee860fb7e5f404db71b8cf264c437 Mon Sep 17 00:00:00 2001 From: liuchao Date: Wed, 19 Jun 2019 18:19:34 +0800 Subject: [PATCH 08/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0=202019=E5=B9=B46=E6=9C=8819=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LongestCommonSequence.java | 32 ++++ .../src/juejin/lc/leetCode/AddTwoNumbers.java | 116 +++++++++++++ .../lc/leetCode/LengthOfLongestSubstring.java | 40 +++++ java/src/juejin/lc/leetCode/ReverseBits.java | 31 ++++ java/src/juejin/lc/leetCode/RobSolution.java | 70 ++++++++ java/src/juejin/lc/leetCode/RotateArrays.java | 163 ++++++++++++++++++ .../src/juejin/lc/leetCode/TitleToNumber.java | 48 ++++++ .../juejin/lc/leetCode/TrailingZeroes.java | 37 ++++ java/src/juejin/lc/leetCode/TwoNum.java | 41 +++++ java/src/juejin/lc/sql/MergeTwoTable.sql | 29 ++++ java/src/juejin/lc/sql/TheSecondSalary.sql | 21 +++ 11 files changed, 628 insertions(+) create mode 100644 java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java create mode 100644 java/src/juejin/lc/leetCode/AddTwoNumbers.java create mode 100644 java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java create mode 100644 java/src/juejin/lc/leetCode/ReverseBits.java create mode 100644 java/src/juejin/lc/leetCode/RobSolution.java create mode 100644 java/src/juejin/lc/leetCode/RotateArrays.java create mode 100644 java/src/juejin/lc/leetCode/TitleToNumber.java create mode 100644 java/src/juejin/lc/leetCode/TrailingZeroes.java create mode 100644 java/src/juejin/lc/leetCode/TwoNum.java create mode 100644 java/src/juejin/lc/sql/MergeTwoTable.sql create mode 100644 java/src/juejin/lc/sql/TheSecondSalary.sql diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java new file mode 100644 index 0000000..4bdc523 --- /dev/null +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java @@ -0,0 +1,32 @@ +package juejin.lc.dynamicProgramming; + +/** + * 最长公共子序列 + * + * @author liuchao + * @date 2019/6/19 + */ +public class LongestCommonSequence { + /** + * str1 = “abcbdab”;str2 = "bdcaba"。 + * + * @param str1 string + * @param str2 string + * @return 返回最长公共子序列长度 + */ + private int solution(String str1, String str2) { +// 状态转移方程公式 +// dp[0][j] = 0; (0<=j<=m) +// dp[i][0] = 0; (0<=i<=n) +// dp[i][j] = dp[i-1][j-1] +1; (str1[i-1] == str2[j-1]) +// dp[i][j] = max{dp[i][j-1],dp[i-1][j]}; (str1[i-1] != str2[j-1]) +// a b c b d a b +// b 0 1 0 1 0 0 1 +// d 0 0 0 0 1 0 0 +// c 0 0 1 0 0 0 0 +// a 1 0 0 0 0 1 0 +// b 0 1 0 1 0 0 1 +// a 1 0 0 0 0 1 0 + return 0; + } +} diff --git a/java/src/juejin/lc/leetCode/AddTwoNumbers.java b/java/src/juejin/lc/leetCode/AddTwoNumbers.java new file mode 100644 index 0000000..dbc9e0a --- /dev/null +++ b/java/src/juejin/lc/leetCode/AddTwoNumbers.java @@ -0,0 +1,116 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.List; + +/** + * 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 单位 数字。 + * + * 如果,我们将这两个数起来相加起来,则会返回出一个新的链表来表示它们的和。 + * + * 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 + * + * 示例: + * + * 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 + * + * @author liuchao + * + */ +public class AddTwoNumbers { + + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + ListNode dummyHead = new ListNode(0); + ListNode p = l1, q = l2, curr = dummyHead; + int carry = 0; + while (p != null || q != null) { + int x = (null != p) ? p.val : 0; + int y = (null != q) ? q.val : 0; + int sum = carry + x + y; + carry = sum / 10; + curr.next = new ListNode(sum % 10); + curr = curr.next; + if (null != p) + p = p.next; + if (null != q) + q = q.next; + } + if (carry > 0) { + curr.next = new ListNode(carry); + } + return dummyHead.next; + } + + public void initListNode() { + ListNode l1 = new ListNode(1); +// l1.next = new ListNode(8); + ListNode l2 = new ListNode(9); + l2.next = new ListNode(9); + + List list = new ArrayList(); + boolean sign = false; + while (null != l1 || null != l2) { + int sum = 0; + if (null == l1) { + sum = l2.val; + } else if (null == l2) { + sum = l1.val; + } else { + sum = l1.val + l2.val; + } + int val = sum >= 10 ? sum - 10 : sum; + if (sign) { + sign = false; + if (val + 1 >= 10) { + sign = true; + } + val = val + 1 >= 10 ? val + 1 - 10 : val + 1; + } + if (sum >= 10) { + sign = true; + } + list.add(val); + if (null != l1) + l1 = l1.next; + if (null != l2) + l2 = l2.next; + } + if (sign) { + list.add(1); + } + ListNode listNode = null; + for (int i = list.size() - 1; i >= 0; i--) { + System.out.println(list.get(i)); + ListNode node = new ListNode(list.get(i)); + if (null == listNode) { + listNode = node; + } else { + node.next = listNode; + listNode = node; + } + } + while (null != listNode) { + System.out.print(listNode.val); + if (listNode.next != null) + System.out.print("-"); + listNode = listNode.next; + } + } + + public static void main(String[] args) { + new AddTwoNumbers().initListNode(); + } + + public class ListNode { + public int val; + ListNode next; + + ListNode() { + + } + + ListNode(int x) { + this.val = x; + } + } +} diff --git a/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java b/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java new file mode 100644 index 0000000..e78d5a7 --- /dev/null +++ b/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java @@ -0,0 +1,40 @@ +package juejin.lc.leetCode; + +import java.util.HashMap; +import java.util.Map; + +/** + * 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 + * + * 示例 1: + * + * 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2: + * + * 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 示例 3: + * + * 输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 + * 的长度,"pwke" 是一个子序列,不是子串。 + * + * @author liuchao + * + */ +public class LengthOfLongestSubstring { + public static int lengthOfLongestSubstring(String s) { + int n = s.length(), ans = 0; + Map map = new HashMap<>(); // current index of character + // try to extend the range [i, j] + for (int j = 0, i = 0; j < n; j++) { + if (map.containsKey(s.charAt(j))) { + i = Math.max(map.get(s.charAt(j)), i); + } + ans = Math.max(ans, j - i + 1); + map.put(s.charAt(j), j + 1); + } + return ans; + } + public static void main(String[] args) { + System.out.println(lengthOfLongestSubstring( "abcabcbb")); + System.out.println(lengthOfLongestSubstring( "bbbbb")); + System.out.println(lengthOfLongestSubstring( "pwwkew")); + } +} diff --git a/java/src/juejin/lc/leetCode/ReverseBits.java b/java/src/juejin/lc/leetCode/ReverseBits.java new file mode 100644 index 0000000..90652fa --- /dev/null +++ b/java/src/juejin/lc/leetCode/ReverseBits.java @@ -0,0 +1,31 @@ +package juejin.lc.leetCode; + +/** + * 颠倒二进制位 + * + * @author liuchao + * @date 2019/6/19 + */ +public class ReverseBits { + /** + * 颠倒给定的 32 位无符号整数的二进制位。 + * 示例 1: + *

+ * 输入: 00000010100101000001111010011100 + * 输出: 00111001011110000010100101000000 + * 解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, + * 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。 + * 示例 2: + *

+ * 输入:11111111111111111111111111111101 + * 输出:10111111111111111111111111111111 + * 解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293, + * 因此返回 3221225471 其二进制表示形式为 10101111110010110010011101101001。 + * + * @param n 32 位无符号整数的二进制位 + * @return 32 位无符号整数的二进制位 + */ + public int solution(int n) { + return Integer.reverse(n); + } +} diff --git a/java/src/juejin/lc/leetCode/RobSolution.java b/java/src/juejin/lc/leetCode/RobSolution.java new file mode 100644 index 0000000..fb23416 --- /dev/null +++ b/java/src/juejin/lc/leetCode/RobSolution.java @@ -0,0 +1,70 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; + +/** + * 打家劫舍 + * + * @author liuchao + * @date 2019/6/19 + */ +public class RobSolution { + /** + * memo[i] 表示考虑抢劫 nums[i...n]表示所能获得的最大收益 + */ + private int[] memo; + + /** + * 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金, + * 影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统, + * 如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 + * 给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。 + * + * @param nums 数据 + * @return 返回值 + */ + public int rob(int[] nums) { +// 思路: 记忆化搜索法 +// ① 状态:考虑抢劫 nums[index...num.length) 这个范围内的所有房子 +// ② 状态转移:tryRob(n) = Max{rob(0) + tryRob(2), rob(1) + tryRob(3)... rob(n-3) + tryRob(n-1), rob(n-2), rob(n-1)} + memo = new int[nums.length]; + //填充数组,默认-1 + Arrays.fill(memo, -1); + return tryRob(nums, 0); + } + + /** + * 尝试 + * + * @param nums 数组 + * @param index 位置 + * @return 返回结果 + */ + private int tryRob(int[] nums, int index) { + if (index >= nums.length) { + return 0; + } + //记忆化搜索可以避免重复子问题的重复运算 + System.out.println("memo[" + index + "] = " + memo[index]); + if (memo[index] != -1) { + return memo[index]; + } + //下面是对状态转移方程的描述 + int res = 0; + for (int i = index; i < nums.length; i++) { + System.out.println("res-before|" + i + ": " + res); + res = Math.max(res, nums[i] + tryRob(nums, i + 2)); + System.out.println("res-after|" + i + ": " + res); + } + System.out.println("res = " + res); + memo[index] = res; + return res; + } + + public static void main(String[] args) { + RobSolution robSolution = new RobSolution(); + int[] nums = {2, 1, 1, 2}; + int res = robSolution.rob(nums); + System.out.println(res); + } +} diff --git a/java/src/juejin/lc/leetCode/RotateArrays.java b/java/src/juejin/lc/leetCode/RotateArrays.java new file mode 100644 index 0000000..bf316f0 --- /dev/null +++ b/java/src/juejin/lc/leetCode/RotateArrays.java @@ -0,0 +1,163 @@ +package juejin.lc.leetCode; + +/** + * 旋转数组 + * + * @author liuchao + * @date 2019/6/19 + */ +public class RotateArrays { + /** + * 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。 + * 示例 1: + * 输入: [1,2,3,4,5,6,7] 和 k = 3 + * 输出: [5,6,7,1,2,3,4] + * 解释: + * 向右旋转 1 步: [7,1,2,3,4,5,6] + * 向右旋转 2 步: [6,7,1,2,3,4,5] + * 向右旋转 3 步: [5,6,7,1,2,3,4] + * 示例 2: + * 输入: [-1,-100,3,99] 和 k = 2 + * 输出: [3,99,-1,-100] + * 解释: + * 向右旋转 1 步: [99,-1,-100,3] + * 向右旋转 2 步: [3,99,-1,-100] + *

+ * 时间复杂度:O(kn) + * 空间复杂度:O(1) + * + * @param nums 数组 + * @param k 步数 + */ + public void rotate(int[] nums, int k) { + //常规思路 + // 第一层for循环 控制步数 + // 第二层for循环做数组位置 + int n = nums.length; + k %= n; + for (int i = 0; i < k; i++) { + int tmp = nums[n - 1]; + for (int j = n - 1; j > 0; j--) { + nums[j] = nums[j - 1]; + } + nums[0] = tmp; + } + } + + /** + * 法2 + * 数组反转 + * 时间复杂度:O(n) + * 空间复杂度:O(1) + * + * @param nums 数组 + * @param k 步数 + */ + private void rotate1(int[] nums, int k) { + int n = nums.length; + k %= n; + print(nums); + reverse(nums, 0, n - 1); + print(nums); + reverse(nums, 0, k - 1); + print(nums); + reverse(nums, k, n - 1); + print(nums); + } + + /** + * 数组反转 + * + * @param nums 数组 + * @param start 开始 + * @param end 结束 + */ + private void reverse(int[] nums, int start, int end) { + while (start < end) { + int tmp = nums[start]; + nums[start++] = nums[end]; + nums[end--] = tmp; + } + } + + /** + * 循环交换 + * 时间复杂度:O(n) + * 空间复杂度:O(1) + * + * @param nums 数组 + * @param k 步数 + */ + private void rotate2(int[] nums, int k) { + int n = nums.length; + k %= n; + // 第一次交换完毕后,前 k 位数字位置正确,后 n-k 位数字中最后 k 位数字顺序错误,继续交换 +// for (int start = 0; start < nums.length && k != 0; n -= k, start += k, k %= n) { +// for (int i = 0; i < k; i++) { +// swap(nums, start + i, nums.length - k + i); +// } +// } + for (int start = 0; start < nums.length && k != 0; n -= k, start += k, k %= n) { + for (int i = 0; i < k; i++) { + swap(nums, start + i, nums.length - k + i); + } + } + } + + /** + * 递归交换 + * 时间复杂度:O(n) + * 空间复杂度:O(n/k) + * + * @param nums 数组 + * @param k 步数 + */ + private void rotate3(int[] nums, int k) { + recursiveSwap(nums, k, 0, nums.length); + } + + /** + * 递归交换 + * + * @param nums 数组 + * @param k 长度 + * @param start 开始 + * @param length 长度 + */ + private void recursiveSwap(int[] nums, int k, int start, int length) { + k %= length; + if (k != 0) { + for (int i = 0; i < k; i++) { + swap(nums, start + i, nums.length - k + i); + } + recursiveSwap(nums, k, start + k, length - k); + } + } + + /** + * 数组之间两两交换 + * + * @param nums 数组 + * @param i i + * @param j j + */ + private void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + + private void print(int[] nums) { + for (int num : nums) { + System.out.print(num + " "); + } + System.out.println(); + } + + public static void main(String[] args) { + RotateArrays rotateArrays = new RotateArrays(); + int[] nums = {1, 2, 3, 4, 5, 6, 7}; + int k = 3; + rotateArrays.rotate1(nums, k); + } +} diff --git a/java/src/juejin/lc/leetCode/TitleToNumber.java b/java/src/juejin/lc/leetCode/TitleToNumber.java new file mode 100644 index 0000000..d2aa43b --- /dev/null +++ b/java/src/juejin/lc/leetCode/TitleToNumber.java @@ -0,0 +1,48 @@ +package juejin.lc.leetCode; + +/** + * Excel表序列号 + * + * @author liuchao + * @date 2019/6/19 + */ +public class TitleToNumber { + /** + * 给定一个Excel表格中的列名称,返回其相应的列序号。 + * 例如, + * A -> 1 + * B -> 2 + * C -> 3 + * ... + * Z -> 26 + * AA -> 27 + * AB -> 28 + * ... + * 示例 1: + * 输入: "A" + * 输出: 1 + * 示例 2: + * 输入: "AB" + * 输出: 28 + * 示例 3: + * 输入: "ZY" + * 输出: 701 + * + * @param s 字符串 + * @return 返回值 + */ + private int solution(String s) { + int sum = 0; + for (int i = 0; i < s.length(); i++) { + sum += Math.pow(26, s.length() - 1 - i) * (s.charAt(i) - 'A' + 1); + } + return sum; + } + + public static void main(String[] args) { + TitleToNumber titleToNumber = new TitleToNumber(); + String s = "ZY"; + int res = titleToNumber.solution(s); + System.out.println(res); + } +} diff --git a/java/src/juejin/lc/leetCode/TrailingZeroes.java b/java/src/juejin/lc/leetCode/TrailingZeroes.java new file mode 100644 index 0000000..9980f02 --- /dev/null +++ b/java/src/juejin/lc/leetCode/TrailingZeroes.java @@ -0,0 +1,37 @@ +package juejin.lc.leetCode; + +/** + * 阶乘后的0 + * + * @author liuchao + * @date 2019/6/19 + */ +public class TrailingZeroes { + /** + * 给定一个整数 n,返回 n! 结果尾数中零的数量。 + * 示例 1: + * 输入: 3 + * 输出: 0 + * 解释: 3! = 6, 尾数中没有零。 + * 示例 2: + * 输入: 5 + * 输出: 1 + * 解释: 5! = 120, 尾数中有 1 个零. + * + * @param n 数值 + * @return 0个数 + */ + public int solution(int n) { + if (n < 5) { + return 0; + } else { + return n / 5 + solution(n / 5); + } + } + + public static void main(String[] args) { + TrailingZeroes trailingZeroes = new TrailingZeroes(); + int res = trailingZeroes.solution(9); + System.out.println(res); + } +} diff --git a/java/src/juejin/lc/leetCode/TwoNum.java b/java/src/juejin/lc/leetCode/TwoNum.java new file mode 100644 index 0000000..9871507 --- /dev/null +++ b/java/src/juejin/lc/leetCode/TwoNum.java @@ -0,0 +1,41 @@ +package juejin.lc.leetCode; + +import java.util.HashMap; +import java.util.Map; + +/** + * 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为gai目标值的 两个 整数。 + * + * 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 + * + * 示例: + * + * 给定 nums = [2, 7, 11, 15], target = 9 + * + * 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] + * + * @author liuchao + * + */ +public class TwoNum { + public static int[] twoNumSum(int[] nums, int target) { + Map map = new HashMap(); + for (int i = 0; i < nums.length; i++) { + int complement = target - nums[i]; + if (map.containsKey(complement)) { + return new int[] { map.get(complement), i }; + } + map.put(nums[i], i); + } + throw new IllegalArgumentException("No two sum solution"); + } + + public static void main(String[] args) { + int[] num = new int[] { 2, 7, 11, 15 }; + int target = 9; + int[] res = twoNumSum(num, target); + for (int i = 0; i < res.length; i++) { + System.out.print(res[i] + " "); + } + } +} diff --git a/java/src/juejin/lc/sql/MergeTwoTable.sql b/java/src/juejin/lc/sql/MergeTwoTable.sql new file mode 100644 index 0000000..5c276a0 --- /dev/null +++ b/java/src/juejin/lc/sql/MergeTwoTable.sql @@ -0,0 +1,29 @@ +Create table Person (PersonId int, FirstName varchar(255), LastName varchar(255)) +Create table Address (AddressId int, PersonId int, City varchar(255), State varchar(255)) +Truncate table Person +insert into Person (PersonId, LastName, FirstName) values ('1', 'Wang', 'Allen') +Truncate table Address +insert into Address (AddressId, PersonId, City, State); + +-- 表1: Person +-- +-------------+---------+ +-- | 列名 | 类型 | +-- +-------------+---------+ +-- | PersonId | int | +-- | FirstName | varchar | +-- | LastName | varchar | +-- +-------------+---------+ +-- PersonId 是上表主键 +-- 表2: Address +-- +-------------+---------+ +-- | 列名 | 类型 | +-- +-------------+---------+ +-- | AddressId | int | +-- | PersonId | int | +-- | City | varchar | +-- | State | varchar | +-- +-------------+---------+ +-- AddressId 是上表主键 +-- 编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息: +-- FirstName, LastName, City, State +select p.FirstName, p.LastName, a.City, a.State from Person p left join Address a on p.PersonId = a.PersonId; \ No newline at end of file diff --git a/java/src/juejin/lc/sql/TheSecondSalary.sql b/java/src/juejin/lc/sql/TheSecondSalary.sql new file mode 100644 index 0000000..3b26787 --- /dev/null +++ b/java/src/juejin/lc/sql/TheSecondSalary.sql @@ -0,0 +1,21 @@ +Create table If Not Exists Employee (Id int, Salary int) +Truncate table Employee +insert into Employee (Id, Salary) values ('1', '100') +insert into Employee (Id, Salary) values ('2', '200') +insert into Employee (Id, Salary) values ('3', '300') + +编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。 ++----+--------+ +| Id | Salary | ++----+--------+ +| 1 | 100 | +| 2 | 200 | +| 3 | 300 | ++----+--------+ +例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。 ++---------------------+ +| SecondHighestSalary | ++---------------------+ +| 200 | ++---------------------+ + select (select distinct salary from Employee order by salary desc limit 1,1) as SecondHighestSalary ; \ No newline at end of file From 520b767fc3fadf733be314040bd9e75d2c60c4c7 Mon Sep 17 00:00:00 2001 From: liuchao Date: Thu, 20 Jun 2019 17:58:46 +0800 Subject: [PATCH 09/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0=202019=E5=B9=B46=E6=9C=8820=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lc/dynamicProgramming/BackPack01.java | 21 +++ .../LongestCommonSequence.java | 50 +++++- .../LongestCommonSubString.java | 159 ++++++++++++++++++ .../LongestIncreasingSubSequence.java | 20 +++ .../dynamicProgramming/MaxSubsequenceSum.java | 24 +++ java/src/juejin/lc/leetCode/RobSolution.java | 43 ++++- 6 files changed, 310 insertions(+), 7 deletions(-) create mode 100644 java/src/juejin/lc/dynamicProgramming/BackPack01.java create mode 100644 java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java create mode 100644 java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java create mode 100644 java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java diff --git a/java/src/juejin/lc/dynamicProgramming/BackPack01.java b/java/src/juejin/lc/dynamicProgramming/BackPack01.java new file mode 100644 index 0000000..161ba0c --- /dev/null +++ b/java/src/juejin/lc/dynamicProgramming/BackPack01.java @@ -0,0 +1,21 @@ +package juejin.lc.dynamicProgramming; + +/** + * 0-1 背包问题 + * @author liuchao + * @date 2019/6/20 + */ +public class BackPack01 { + /** + * 穷举 回溯 动态规划 递归 贪心算法 + * @param nums 数组 + * @param max 重量 + */ + private void solution(int[] nums,int max){ +// 状态转移方程 +// 假设有N件物品和一个容量为V的背包。第i件物品的体积是v[i],价值是c[i],将哪些物品装入背包可使价值总和最大? +// 每一种物品都有两种可能即放入背包或者不放入背包。 +// 可以用dp[i][j]表示第i件物品放入容量为j的背包所得的最大价值,则状态转移方程可以推出如下: +// dp[i][j]=max{dp[i-1][j-v[i]]+c[i],dp[i-1][j]}; + } +} diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java index 4bdc523..5235d0e 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java @@ -9,12 +9,12 @@ public class LongestCommonSequence { /** * str1 = “abcbdab”;str2 = "bdcaba"。 - * - * @param str1 string - * @param str2 string + * 4 + * @param s1 string + * @param s2 string * @return 返回最长公共子序列长度 */ - private int solution(String str1, String str2) { + private int solution(String s1, String s2) { // 状态转移方程公式 // dp[0][j] = 0; (0<=j<=m) // dp[i][0] = 0; (0<=i<=n) @@ -27,6 +27,46 @@ private int solution(String str1, String str2) { // a 1 0 0 0 0 1 0 // b 0 1 0 1 0 0 1 // a 1 0 0 0 0 1 0 - return 0; + char[] str1 = s1.toCharArray(); + char[] str2 = s2.toCharArray(); + int[][] dp = new int[str1.length][str2.length]; + for (int i = 0; i < str1.length; i++) { + if (str1[i] == str2[0]){ + dp[i][0] = 1; + }else{ + dp[i][0] = 0; + } + } + for (int j = 0; j < str2.length; j++) { + if (str2[j] == str1[0]){ + dp[0][j] = 1; + }else{ + dp[0][j] = 0; + } + } + for (int i = 1; i < str1.length; i++) { + for (int j = 1; j < str2.length; j++) { + if (str1[i] == str2[j]){ + dp[i][j] = dp[i-1][j-1] +1; + }else{ + dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]); + } + } + } + int length = 0; + for (int i = 0; i < str1.length; i++) { + for (int j = 0; j < str2.length; j++) { + length = Math.max(length,dp[i][j]); + } + } + return length; + } + + public static void main(String[] args) { + LongestCommonSequence longestCommonSubString = new LongestCommonSequence(); + String s1 = "abcbdab"; + String s2 = "bdcaba"; + int res = longestCommonSubString.solution(s1,s2); + System.out.println(res); } } diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java new file mode 100644 index 0000000..9eb90c2 --- /dev/null +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java @@ -0,0 +1,159 @@ +package juejin.lc.dynamicProgramming; + +import java.util.Arrays; + +/** + * 最长公共子串 + * + * @author liuchao + * @date 2019/6/19 + */ +public class LongestCommonSubString { + /** + * str1=“abc”,str2=”caba”,则str1,str2的最长公共子串为ab。 + * + * @param str1 string + * @param str2 string + * @return 返回最长公共子串 + */ + private String solution(String str1, String str2) { +// 构建二阶矩阵 +// a b c +// c 0 0 1 +// a 1 0 0 +// b 0 2 0 +// a 1 0 0 +// 状态转移方程公式 +// dp[0][j] = 0; (0<=j<=m) +// dp[i][0] = 0; (0<=i<=n) +// dp[i][j] = dp[i-1][j-1] +1; (str1[i] == str2[j]) +// dp[i][j] = 0; (str1[i] != str2[j]) + int[][] dp = new int[str1.length()][str2.length()]; + char[] str1Chars = str1.toCharArray(); + char[] str2Chars = str2.toCharArray(); + //对矩阵第一列赋值 + for (int i = 0; i < str1Chars.length; i++) { + if (str1Chars[i] == str2Chars[0]) { + dp[i][0] = 1; + } else { + dp[i][0] = 0; + } + } +// System.out.println("第一列:"); +// print(dp); + //对矩阵第一行赋值 + for (int j = 0; j < str2Chars.length; j++) { + if (str2Chars[j] == str1Chars[0]) { + dp[0][j] = 1; + } else { + dp[0][j] = 0; + } + } +// System.out.println("第一行:"); +// print(dp); + for (int i = 1; i < str1Chars.length; i++) { + for (int j = 1; j < str2Chars.length; j++) { + if (str1Chars[i] == str2Chars[j]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = 0; + } + } + } + System.out.println("完整矩阵:"); + print(dp); + int max = dp[0][0]; + //--> j + int x = 0; + // --> i + int y = 0; + for (int i = 0; i < str1Chars.length; i++) { + for (int j = 0; j < str2Chars.length; j++) { + if (dp[i][j] > max) { + max = dp[i][j]; + y = i; + x = j; + } +// max = Math.max(max,dp[i][j]); + } + } + System.out.println(max + "," + x + "," + y); + + return resJoint(str1, x, y); + } + + /** + * 优化 + * 根据解法1可以找到规律,求最长公共子串可以转换为求二阶矩阵的最大递增对角线问题 + * a b c + * c 0 0 1 + * a 1 0 0 + * b 0 2 0 + * a 1 0 0 + * 求 2 1 + * + * @param str1 string + * @param str2 string + * @return 返回最长公共子串 + */ + private String solution2(String str1, String str2) { + char[] str1Chars = str1.toCharArray(); + char[] str2Chars = str2.toCharArray(); + int x = 0; + int y = 0; + int index = 0; + int max = 0; + //列 + int row = 0; + //行 + int col = str2Chars.length - 1; + //计算矩阵中的每一条斜对角线上的值 + while (row < str1Chars.length) { + int i = row; + int j = col; + while (i < str1Chars.length && j < str2Chars.length) { + if (str1Chars[i] == str2Chars[j]) { + if (++index > max) { + max = index; + x = j; + y = i; + } + } else { + index = 0; + } + i++; + j++; + } + if (col > 0) { + --col; + } else { + ++row; + } + } + System.out.println(max + "," + x + "," + y); + return resJoint(str1, x, y); + } + + private void print(int[][] dp) { + for (int[] ds : dp) { + System.out.println(Arrays.toString(ds)); + } + } + + private String resJoint(String str, int x, int y) { + StringBuilder stringBuilder = new StringBuilder(); + while (x >= 0 && y >= 0) { + stringBuilder.append(str.charAt(y--)); + --x; + } + return stringBuilder.reverse().toString(); + } + + public static void main(String[] args) { + LongestCommonSubString longestCommonSubString = new LongestCommonSubString(); + String str1 = "bab"; + String str2 = "caba"; + String res = longestCommonSubString.solution(str1, str2); + System.out.println("最长公共子串为:" + res); + } +} diff --git a/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java b/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java new file mode 100644 index 0000000..f1fb4e8 --- /dev/null +++ b/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java @@ -0,0 +1,20 @@ +package juejin.lc.dynamicProgramming; + +/** + * 最长递增子序列 + * @author liuchao + * @date 2019/6/19 + */ +public class LongestIncreasingSubSequence { + /** + * 最长递增子序列(Longest Increasing Subsequence)是指找到一个给定序列的最长子序列的长度,使得子序列中的所有元素单调递增。 + * 例如:{ 3,5,7,1,2,8 } 的 LIS 是 { 3,5,7,8 },长度为 4。 + * @param s 字符串 + * @return 返回长度 + */ + private int solution(String s){ + //推公式 + //F[x] = max{1,F[i]+1|ai=0 && i == 1) +// dp[i] = dp[i-1]+ai; (ai>=0 && i>=2) +// dp[i] = 0; (dp[i-1] + ai <=0 && i>=2) +// 比如 [-2,1,-3,4,-1,2,1,-5,4] +// 取连续子数组 [4,-1,2,1] 的和最大,为 6 + return 0; + + } +} diff --git a/java/src/juejin/lc/leetCode/RobSolution.java b/java/src/juejin/lc/leetCode/RobSolution.java index fb23416..c802963 100644 --- a/java/src/juejin/lc/leetCode/RobSolution.java +++ b/java/src/juejin/lc/leetCode/RobSolution.java @@ -23,7 +23,7 @@ public class RobSolution { * @param nums 数据 * @return 返回值 */ - public int rob(int[] nums) { + private int rob(int[] nums) { // 思路: 记忆化搜索法 // ① 状态:考虑抢劫 nums[index...num.length) 这个范围内的所有房子 // ② 状态转移:tryRob(n) = Max{rob(0) + tryRob(2), rob(1) + tryRob(3)... rob(n-3) + tryRob(n-1), rob(n-2), rob(n-1)} @@ -35,6 +35,7 @@ public int rob(int[] nums) { /** * 尝试 + * 自顶向上 * * @param nums 数组 * @param index 位置 @@ -61,10 +62,48 @@ private int tryRob(int[] nums, int index) { return res; } + /** + * 自底向下 动态规划 + * + * @param nums 数组 + * @return 返回结果 + */ + private int rob2(int[] nums) { + int n = nums.length; + if (n == 0) { + return 0; + } + // memo[i] 表示考虑抢劫 nums[i...n-1] 所能获得最大收益(不是说一定从 i 开始抢劫) + int[] memo = new int[n]; + // 先考虑最简单的情况 + memo[n - 1] = nums[n - 1]; + for (int i = n - 2; i >= 0; i--) { + // memo[i] 的取值在考虑抢劫 i 号房子和不考虑抢劫之间取最大值 + memo[i] = Math.max(nums[i] + (i + 2 >= n ? 0 : memo[i + 2]), nums[i + 1] + (i + 3 >= n ? 0 : memo[i + 3])); + } + return memo[0]; + } + + private int solution(int[] nums) { + int n = nums.length; + if (n <= 1) { + return n == 0 ? 0 : nums[0]; + } + int[] memo = new int[n]; + memo[0] = nums[0]; + memo[1] = Math.max(nums[0], nums[1]); + System.out.println(memo[0] + "," + memo[1]); + for (int i = 2; i < n; i++) { + System.out.println("memo[i - 1]=" + memo[i - 1] + ",nums[i]=" + nums[i] + ",memo[i - 2] =" + memo[i - 2] + " ,i=" + i); + memo[i] = Math.max(memo[i - 1], nums[i] + memo[i - 2]); + } + return memo[n - 1]; + } + public static void main(String[] args) { RobSolution robSolution = new RobSolution(); int[] nums = {2, 1, 1, 2}; - int res = robSolution.rob(nums); + int res = robSolution.solution(nums); System.out.println(res); } } From 5b73cfdf60aefe86ee88cb9787e02a1320124af5 Mon Sep 17 00:00:00 2001 From: liuchao Date: Thu, 22 Aug 2019 17:29:08 +0800 Subject: [PATCH 10/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0=202019=E5=B9=B46=E6=9C=8820=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/IsHappy.java | 34 +++++++++++++++++++ .../lc/leetCode/NarcissisticNumber.java | 27 +++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/IsHappy.java create mode 100644 java/src/juejin/lc/leetCode/NarcissisticNumber.java diff --git a/java/src/juejin/lc/leetCode/IsHappy.java b/java/src/juejin/lc/leetCode/IsHappy.java new file mode 100644 index 0000000..f997ce2 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsHappy.java @@ -0,0 +1,34 @@ +package juejin.lc.leetCode; + +import java.util.HashMap; +import java.util.Map; + +/** + * 肥宅快乐数 + * + * @author liuchao + * @date 2019/7/15 + */ +public class IsHappy { + private Map map = new HashMap(); + /** + * 一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1, + * 也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。 + * 输入: 19 + * 输出: true + * 解释: + * 12 + 92 = 82 + * 82 + 22 = 68 + * 62 + 82 = 100 + * 12 + 02 + 02 = 1 + * + * @param n 快乐数 + * @return 返回结果 + */ + private boolean solution(int n) { + return true; + } + + public static void main(String[] args) { + } +} diff --git a/java/src/juejin/lc/leetCode/NarcissisticNumber.java b/java/src/juejin/lc/leetCode/NarcissisticNumber.java new file mode 100644 index 0000000..87580e5 --- /dev/null +++ b/java/src/juejin/lc/leetCode/NarcissisticNumber.java @@ -0,0 +1,27 @@ +package juejin.lc.leetCode; + +/** + * 水仙花数 + * 求1000以内的水仙花数 + * 153,370,371,407 + * 153 = 1*1*1 + 5*5*5 + 3 * 3 * 3; + * @author liuchao + * @date 2019/8/22 + */ +public class NarcissisticNumber { + private static void solution (){ + // 首先一定是三位数 + for (int i = 100; i < 1000; i++) { + int unit = i % 10; + int ten = (i / 10) % 10; + int hundred = (i / 10 / 10) % 10; + if(i == (unit * unit * unit + ten * ten * ten + hundred * hundred * hundred)){ + System.out.println(i + " "); + } + } + } + + public static void main(String[] args) { + solution(); + } +} From 8e7eca934bd4acadf24b67e5e620d4b50f44ffee Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Fri, 11 Oct 2019 17:14:12 +0800 Subject: [PATCH 11/43] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=201.?= =?UTF-8?q?=E6=9C=80=E9=95=BF=E5=85=AC=E5=85=B1=E5=AD=90=E4=B8=B2=202.?= =?UTF-8?q?=E6=9C=80=E9=95=BF=E5=85=AC=E5=85=B1=E5=AD=90=E5=BA=8F=E5=88=97?= =?UTF-8?q?=203.=E6=9C=80=E9=95=BF=E9=80=92=E5=A2=9E=EF=BC=88=E5=87=8F?= =?UTF-8?q?=EF=BC=89=E5=AD=90=E5=BA=8F=E5=88=97=204.=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E5=AD=90=E5=BA=8F=E5=88=97=E5=92=8C=E9=98=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LongestCommonSequence.java | 31 ++++++++---- .../LongestCommonSubString.java | 24 ++++----- .../LongestIncreasingSubSequence.java | 37 +++++++++++--- .../dynamicProgramming/MaxSubsequenceSum.java | 49 ++++++++++++++++--- 4 files changed, 109 insertions(+), 32 deletions(-) diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java index 5235d0e..dbe7763 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java @@ -1,5 +1,7 @@ package juejin.lc.dynamicProgramming; +import java.util.Arrays; + /** * 最长公共子序列 * @@ -8,7 +10,7 @@ */ public class LongestCommonSequence { /** - * str1 = “abcbdab”;str2 = "bdcaba"。 + * s1 = “abcbdab”;s2 = "bdcaba"。 * 4 * @param s1 string * @param s2 string @@ -20,13 +22,14 @@ private int solution(String s1, String s2) { // dp[i][0] = 0; (0<=i<=n) // dp[i][j] = dp[i-1][j-1] +1; (str1[i-1] == str2[j-1]) // dp[i][j] = max{dp[i][j-1],dp[i-1][j]}; (str1[i-1] != str2[j-1]) -// a b c b d a b -// b 0 1 0 1 0 0 1 -// d 0 0 0 0 1 0 0 -// c 0 0 1 0 0 0 0 -// a 1 0 0 0 0 1 0 -// b 0 1 0 1 0 0 1 -// a 1 0 0 0 0 1 0 +// b d c a b a +// a [0, 0, 0, 1, 0, 1] +// b [1, 1, 1, 1, 2, 2] +// c [0, 1, 2, 2, 2, 2] +// b [1, 1, 2, 2, 3, 3] +// d [0, 2, 2, 2, 3, 3] +// a [0, 2, 2, 3, 3, 4] +// b [1, 2, 2, 3, 4, 4] char[] str1 = s1.toCharArray(); char[] str2 = s2.toCharArray(); int[][] dp = new int[str1.length][str2.length]; @@ -53,15 +56,25 @@ private int solution(String s1, String s2) { } } } + print(dp); int length = 0; + StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < str1.length; i++) { for (int j = 0; j < str2.length; j++) { + if (dp[i][j] == length && stringBuilder.indexOf(String.valueOf(str1[i])) == -1) { + stringBuilder.append(str1[i]); + } length = Math.max(length,dp[i][j]); } } + System.out.println(stringBuilder.reverse().toString()); return length; } - + private void print(int[][] dp) { + for (int[] ds : dp) { + System.out.println(Arrays.toString(ds)); + } + } public static void main(String[] args) { LongestCommonSequence longestCommonSubString = new LongestCommonSequence(); String s1 = "abcbdab"; diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java index 9eb90c2..64eb367 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java @@ -18,11 +18,12 @@ public class LongestCommonSubString { */ private String solution(String str1, String str2) { // 构建二阶矩阵 -// a b c -// c 0 0 1 -// a 1 0 0 -// b 0 2 0 -// a 1 0 0 +// str1 a b c +// str2 0 0 0 0 +// c 0 0 0 1 +// a 0 1 0 0 +// b 0 0 2 0 +// a 0 1 0 0 // 状态转移方程公式 // dp[0][j] = 0; (0<=j<=m) // dp[i][0] = 0; (0<=i<=n) @@ -85,11 +86,12 @@ private String solution(String str1, String str2) { /** * 优化 * 根据解法1可以找到规律,求最长公共子串可以转换为求二阶矩阵的最大递增对角线问题 - * a b c - * c 0 0 1 - * a 1 0 0 - * b 0 2 0 - * a 1 0 0 + // str1 a b c + // str2 0 0 0 0 + // c 0 0 0 1 + // a 0 1 0 0 + // b 0 0 2 0 + // a 0 1 0 0 * 求 2 1 * * @param str1 string @@ -151,7 +153,7 @@ private String resJoint(String str, int x, int y) { public static void main(String[] args) { LongestCommonSubString longestCommonSubString = new LongestCommonSubString(); - String str1 = "bab"; + String str1 = "abc"; String str2 = "caba"; String res = longestCommonSubString.solution(str1, str2); System.out.println("最长公共子串为:" + res); diff --git a/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java b/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java index f1fb4e8..7edb624 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java @@ -7,14 +7,39 @@ */ public class LongestIncreasingSubSequence { /** - * 最长递增子序列(Longest Increasing Subsequence)是指找到一个给定序列的最长子序列的长度,使得子序列中的所有元素单调递增。 - * 例如:{ 3,5,7,1,2,8 } 的 LIS 是 { 3,5,7,8 },长度为 4。 - * @param s 字符串 + * 最长递增子序列(Longest Increasing Subsequence)是指找到一个给定序列的最长子序列的长度,使得子序列中的所有元素单调递增。 + * 例如:{ 3,5,7,1,2,8 } 的 LIS 是 { 3,5,7,8 },长度为 4。 + * @param nums 数组 * @return 返回长度 */ - private int solution(String s){ + private int solution(int[] nums){ //推公式 - //F[x] = max{1,F[i]+1|ai max) { + max = F[i]; + } + System.out.println("F[" + i + "] = " + F[i]); + } + System.out.println(); + return max; + } + + public static void main(String[] args) { + int[] nums = { 3,5,7,1,2,8 }; + int res = new LongestIncreasingSubSequence().solution(nums); + System.out.println(res); } } diff --git a/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java b/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java index d439c04..842fe03 100644 --- a/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java +++ b/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java @@ -13,12 +13,49 @@ public class MaxSubsequenceSum { */ private int solution(int[] nums){ // 状态转移方程公式 -// dp[1] = a1; (a1>=0 && i == 1) -// dp[i] = dp[i-1]+ai; (ai>=0 && i>=2) -// dp[i] = 0; (dp[i-1] + ai <=0 && i>=2) -// 比如 [-2,1,-3,4,-1,2,1,-5,4] -// 取连续子数组 [4,-1,2,1] 的和最大,为 6 - return 0; +// dp[0] = ai; (i = 0) +// dp[i] = dp[i-1]>=0 ? dp[i-1]+nums[i] : nums[i] (i > 1) + int[] dp = new int[nums.length]; + dp[0] = nums[0]; + for (int i = 1; i < nums.length; i++) { + if(dp[i - 1] >= 0) { + dp[i] = dp[i - 1] + nums[i]; + }else { + dp[i] = nums[i]; + } + System.out.println("dp[" + i + "] = " + dp[i]); + } +// 取dp里面最大值即可 + int res = dp[0]; + for (int i = 1; i < dp.length; i++) { + if(dp[i] > res) { + res = dp[i]; + } + } + return res; + } + /** + * 最优解 + * @param nums 传入数组 + * @return 返回值 + */ + private int solution2(int[] nums){ + int res = nums[0]; + int sum = 0; + for(int num: nums) { + if(sum > 0) { + sum += num; + } else { + sum = num; + } + res = Math.max(res, sum); + } + return res; + } + public static void main(String[] args) { + int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; + int res = new MaxSubsequenceSum().solution2(nums); + System.out.println("最大子序列和为:" + res); } } From 275b818549a59c71d26f8f5c2bc7fe489b09fa8f Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Mon, 14 Oct 2019 17:46:40 +0800 Subject: [PATCH 12/43] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92-01?= =?UTF-8?q?=E8=83=8C=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lc/dynamicProgramming/BackPack01.java | 68 +++++++++++++++++-- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/java/src/juejin/lc/dynamicProgramming/BackPack01.java b/java/src/juejin/lc/dynamicProgramming/BackPack01.java index 161ba0c..9ce6ddc 100644 --- a/java/src/juejin/lc/dynamicProgramming/BackPack01.java +++ b/java/src/juejin/lc/dynamicProgramming/BackPack01.java @@ -1,21 +1,79 @@ package juejin.lc.dynamicProgramming; +import java.util.Arrays; + /** * 0-1 背包问题 + * * @author liuchao * @date 2019/6/20 */ public class BackPack01 { /** * 穷举 回溯 动态规划 递归 贪心算法 - * @param nums 数组 - * @param max 重量 + * + * @param v 体积 + * @param p 重量 + * @param c 总重量 */ - private void solution(int[] nums,int max){ + private int solution(int[] v, int[] p, int c) { // 状态转移方程 -// 假设有N件物品和一个容量为V的背包。第i件物品的体积是v[i],价值是c[i],将哪些物品装入背包可使价值总和最大? +// 假设有N件物品和一个容量为V的背包。第i件物品的体积是v[i],价值是p[i],将哪些物品装入背包可使价值总和最大? // 每一种物品都有两种可能即放入背包或者不放入背包。 // 可以用dp[i][j]表示第i件物品放入容量为j的背包所得的最大价值,则状态转移方程可以推出如下: -// dp[i][j]=max{dp[i-1][j-v[i]]+c[i],dp[i-1][j]}; +// dp[i][0] = dp[0][j] = 0 (i > 0,j > 0) +// dp[i][j] = dp[i-1][j] (j < v[i]) +// dp[i][j] = max{dp[i-1][j], v[i-1][j-v[i]]+p[i]} +// 0 1 2 3 4 5 6 7 8 +// 0 [0, 0, 0, 0, 0, 0, 0, 0, 0] +// 1 [0, 0, 3, 3, 3, 3, 3, 3, 3] +// 2 [0, 0, 3, 4, 4, 7, 7, 7, 7] +// 3 [0, 0, 3, 4, 5, 7, 8, 9, 9] +// 4 [0, 0, 3, 4, 5, 7, 8, 9, 10] + int[][] dp = new int[v.length][c + 1]; + for (int i = 1; i < v.length; i++) { + for (int j = 1; j < c + 1; j++) { + if (j < v[i]) { + dp[i][j] = dp[i - 1][j]; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - v[i]] + p[i]); + } + } + } + print(dp); + int[] items = new int[v.length]; + situation(items, v, p, dp, v.length - 1, c); + System.out.println("回溯选中的物品:(1表示选中)"); + System.out.println("体积:" + Arrays.toString(v)); + System.out.println("价格:" + Arrays.toString(p)); + System.out.println("选中:" + Arrays.toString(items)); + return dp[v.length - 1][c]; + } + + private void situation(int[] items, int[] v, int[] p, int[][] dp, int i, int j) { + if (i > 0) { + if (dp[i][j] == dp[i - 1][j]) { + situation(items, v, p, dp, i - 1, j); + } else if (j - v[i] >= 0 && dp[i][j] == dp[i - 1][j - v[i]] + p[i]) { + items[i] = 1; + situation(items, v, p, dp, i - 1, j -v[i]); + } + } + } + + private void print(int[][] dp) { + for (int[] ds : dp) { + System.out.println(Arrays.toString(ds)); + } + } + + public static void main(String[] args) { + // 0 占位 + int[] v = {0, 2, 3, 4, 5}; + int[] p = {0, 3, 4, 5, 6}; + int c = 8; + BackPack01 backPack01 = new BackPack01(); + int max = backPack01.solution(v, p, c); + System.out.println("当体积为" + c + "时,最大价值为" + max); } } From e677b199046cf3826514af651a601025ddbf57fc Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Tue, 15 Oct 2019 09:30:06 +0800 Subject: [PATCH 13/43] update REMADE.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 95b8bcd..2f62353 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Progress Every Day ## 传送门 +### [01背包](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/BackPack01.java) +### [最大子序列和](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java) +### [最长递增子序列](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java) +### [最长公共子串](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java) +### [最长公共子序列](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java) ### [正则表达式匹配算法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/Pattern.java) ### [AVL树](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/tree/AVLTree.java) ### [N皇后](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/leetCode/SolveNQueens.java) From cf69500b235d04fdc2500ebf3535284ec83f91e3 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Wed, 16 Oct 2019 09:37:50 +0800 Subject: [PATCH 14/43] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=20bu?= =?UTF-8?q?gfix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lc/dynamicProgramming/BackPack01.java | 2 +- .../LongestCommonSequence.java | 4 +- .../LongestCommonSubString.java | 49 +++++++++---------- .../dynamicProgramming/MaxSubsequenceSum.java | 2 +- 4 files changed, 27 insertions(+), 30 deletions(-) diff --git a/java/src/juejin/lc/dynamicProgramming/BackPack01.java b/java/src/juejin/lc/dynamicProgramming/BackPack01.java index 9ce6ddc..ba42afe 100644 --- a/java/src/juejin/lc/dynamicProgramming/BackPack01.java +++ b/java/src/juejin/lc/dynamicProgramming/BackPack01.java @@ -23,7 +23,7 @@ private int solution(int[] v, int[] p, int c) { // 可以用dp[i][j]表示第i件物品放入容量为j的背包所得的最大价值,则状态转移方程可以推出如下: // dp[i][0] = dp[0][j] = 0 (i > 0,j > 0) // dp[i][j] = dp[i-1][j] (j < v[i]) -// dp[i][j] = max{dp[i-1][j], v[i-1][j-v[i]]+p[i]} +// dp[i][j] = max{dp[i-1][j], dp[i-1][j-v[i]]+p[i]} // 0 1 2 3 4 5 6 7 8 // 0 [0, 0, 0, 0, 0, 0, 0, 0, 0] // 1 [0, 0, 3, 3, 3, 3, 3, 3, 3] diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java index dbe7763..33fb23c 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java @@ -20,8 +20,8 @@ private int solution(String s1, String s2) { // 状态转移方程公式 // dp[0][j] = 0; (0<=j<=m) // dp[i][0] = 0; (0<=i<=n) -// dp[i][j] = dp[i-1][j-1] +1; (str1[i-1] == str2[j-1]) -// dp[i][j] = max{dp[i][j-1],dp[i-1][j]}; (str1[i-1] != str2[j-1]) +// dp[i][j] = dp[i-1][j-1] +1; (str1[i] == str2[j]) +// dp[i][j] = max{dp[i][j-1],dp[i-1][j]}; (str1[i] != str2[j]) // b d c a b a // a [0, 0, 0, 1, 0, 1] // b [1, 1, 1, 1, 2, 2] diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java index 64eb367..f020b28 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java @@ -10,7 +10,7 @@ */ public class LongestCommonSubString { /** - * str1=“abc”,str2=”caba”,则str1,str2的最长公共子串为ab。 + * str1 = “abcbdab”;str2 = "bdcaba",则str1,str2的最长公共子串为ab。 * * @param str1 string * @param str2 string @@ -18,21 +18,23 @@ public class LongestCommonSubString { */ private String solution(String str1, String str2) { // 构建二阶矩阵 -// str1 a b c -// str2 0 0 0 0 -// c 0 0 0 1 -// a 0 1 0 0 -// b 0 0 2 0 -// a 0 1 0 0 +// b d c a b a +// a [0, 0, 0, 1, 0, 1] +// b [1, 0, 0, 0, 2, 0] +// c [0, 0, 1, 0, 0, 0] +// b [1, 0, 0, 0, 1, 0] +// d [0, 2, 0, 0, 0, 0] +// a [0, 0, 0, 1, 0, 1] +// b [1, 0, 0, 0, 2, 0] // 状态转移方程公式 -// dp[0][j] = 0; (0<=j<=m) -// dp[i][0] = 0; (0<=i<=n) +// dp[i][0] = 0; (0<=i<=m) +// dp[0][j] = 0; (0<=j<=n) // dp[i][j] = dp[i-1][j-1] +1; (str1[i] == str2[j]) // dp[i][j] = 0; (str1[i] != str2[j]) int[][] dp = new int[str1.length()][str2.length()]; char[] str1Chars = str1.toCharArray(); char[] str2Chars = str2.toCharArray(); - //对矩阵第一列赋值 + for (int i = 0; i < str1Chars.length; i++) { if (str1Chars[i] == str2Chars[0]) { dp[i][0] = 1; @@ -40,9 +42,6 @@ private String solution(String str1, String str2) { dp[i][0] = 0; } } -// System.out.println("第一列:"); -// print(dp); - //对矩阵第一行赋值 for (int j = 0; j < str2Chars.length; j++) { if (str2Chars[j] == str1Chars[0]) { dp[0][j] = 1; @@ -50,8 +49,6 @@ private String solution(String str1, String str2) { dp[0][j] = 0; } } -// System.out.println("第一行:"); -// print(dp); for (int i = 1; i < str1Chars.length; i++) { for (int j = 1; j < str2Chars.length; j++) { if (str1Chars[i] == str2Chars[j]) { @@ -61,7 +58,6 @@ private String solution(String str1, String str2) { } } } - System.out.println("完整矩阵:"); print(dp); int max = dp[0][0]; //--> j @@ -75,7 +71,6 @@ private String solution(String str1, String str2) { y = i; x = j; } -// max = Math.max(max,dp[i][j]); } } System.out.println(max + "," + x + "," + y); @@ -86,12 +81,14 @@ private String solution(String str1, String str2) { /** * 优化 * 根据解法1可以找到规律,求最长公共子串可以转换为求二阶矩阵的最大递增对角线问题 - // str1 a b c - // str2 0 0 0 0 - // c 0 0 0 1 - // a 0 1 0 0 - // b 0 0 2 0 - // a 0 1 0 0 + * b d c a b a + * a [0, 0, 0, 1, 0, 1] + * b [1, 0, 0, 0, 2, 0] + * c [0, 0, 1, 0, 0, 0] + * b [1, 0, 0, 0, 1, 0] + * d [0, 2, 0, 0, 0, 0] + * a [0, 0, 0, 1, 0, 1] + * b [1, 0, 0, 0, 2, 0] * 求 2 1 * * @param str1 string @@ -153,9 +150,9 @@ private String resJoint(String str, int x, int y) { public static void main(String[] args) { LongestCommonSubString longestCommonSubString = new LongestCommonSubString(); - String str1 = "abc"; - String str2 = "caba"; - String res = longestCommonSubString.solution(str1, str2); + String s1 = "abcbdab"; + String s2 = "bdcaba"; + String res = longestCommonSubString.solution2(s1, s2); System.out.println("最长公共子串为:" + res); } } diff --git a/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java b/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java index 842fe03..06c5c76 100644 --- a/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java +++ b/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java @@ -55,7 +55,7 @@ private int solution2(int[] nums){ public static void main(String[] args) { int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; - int res = new MaxSubsequenceSum().solution2(nums); + int res = new MaxSubsequenceSum().solution(nums); System.out.println("最大子序列和为:" + res); } } From 180c2440b206ec07de7f8da2645fefac3bc98d0f Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Fri, 25 Oct 2019 17:28:25 +0800 Subject: [PATCH 15/43] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8Fid=E9=9A=8F?= =?UTF-8?q?=E6=9C=BA=E7=94=9F=E6=88=90=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/other/IdWorker.java | 114 +++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 java/src/juejin/lc/other/IdWorker.java diff --git a/java/src/juejin/lc/other/IdWorker.java b/java/src/juejin/lc/other/IdWorker.java new file mode 100644 index 0000000..c60985a --- /dev/null +++ b/java/src/juejin/lc/other/IdWorker.java @@ -0,0 +1,114 @@ +package juejin.lc.other; + +/** + * snowflake 算法是 twitter 开源的分布式 id 生成算法,采用 Scala 语言实现, + * 是把一个 64 位的 long 型的 id,1 个 bit 是不用的,用其中的 41 bit 作为毫秒数, + * 用 10 bit 作为工作机器 id,12 bit 作为序列号。 + */ +public class IdWorker { + private long workerId; + private long datacenterId; + private long sequence; + + private long twepoch = 1288834974657L; + + private long workerIdBits = 5L; + private long datacenterIdBits = 5L; + + /** + * 这个是二进制运算,就是 5 bit最多只能有31个数字,也就是说机器id最多只能是32以内 + */ + private long maxWorkerId = -1L ^ (-1L << workerIdBits); + + + private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); + private long sequenceBits = 12L; + + private long workerIdShift = sequenceBits; + private long datacenterIdShift = sequenceBits + workerIdBits; + private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + private long sequenceMask = -1L ^ (-1L << sequenceBits); + + private long lastTimestamp = -1L; + + public IdWorker(long workerId, long datacenterId, long sequence) { + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException( + String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + } + if (datacenterId > maxDatacenterId || datacenterId < 0) { + throw new IllegalArgumentException( + String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); + } + System.out.printf( + "worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d", + timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId); + + this.workerId = workerId; + this.datacenterId = datacenterId; + this.sequence = sequence; + } + public long getWorkerId() { + return workerId; + } + + public long getDatacenterId() { + return datacenterId; + } + + public long getTimestamp() { + return System.currentTimeMillis(); + } + + public synchronized long nextId() { + // 这儿就是获取当前时间戳,单位是毫秒 + long timestamp = timeGen(); + + if (timestamp < lastTimestamp) { + System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp); + throw new RuntimeException(String.format( + "Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + if (lastTimestamp == timestamp) { + // 这个意思是说一个毫秒内最多只能有4096个数字 + // 无论你传递多少进来,这个位运算保证始终就是在4096这个范围内,避免你自己传递个sequence超过了4096这个范围 + sequence = (sequence + 1) & sequenceMask; + if (sequence == 0) { + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0; + } + + // 这儿记录一下最近一次生成id的时间戳,单位是毫秒 + lastTimestamp = timestamp; + + // 这儿就是将时间戳左移,放到 41 bit那儿; + // 将机房 id左移放到 5 bit那儿; + // 将机器id左移放到5 bit那儿;将序号放最后12 bit; + // 最后拼接起来成一个 64 bit的二进制数字,转换成 10 进制就是个 long 型 + return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) | sequence; + } + + private long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + private long timeGen() { + return System.currentTimeMillis(); + } + + // ---------------测试--------------- + public static void main(String[] args) { + IdWorker worker = new IdWorker(1, 1, 1); + for (int i = 0; i < 30; i++) { + System.out.println(worker.nextId()); + } + } +} From b009f1be08ee058e013f88aedd78afc74f06546e Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Tue, 5 Nov 2019 20:35:49 +0800 Subject: [PATCH 16/43] LeetCode -- isHappy --- java/src/juejin/lc/leetCode/CountAndSay.java | 6 ++-- .../src/juejin/lc/leetCode/HammingWeight.java | 21 ++++++++++++ java/src/juejin/lc/leetCode/IsHappy.java | 32 ++++++++++++++++--- 3 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 java/src/juejin/lc/leetCode/HammingWeight.java diff --git a/java/src/juejin/lc/leetCode/CountAndSay.java b/java/src/juejin/lc/leetCode/CountAndSay.java index c0bc4dc..ee00b2a 100644 --- a/java/src/juejin/lc/leetCode/CountAndSay.java +++ b/java/src/juejin/lc/leetCode/CountAndSay.java @@ -2,7 +2,7 @@ /** * 1 被读作 "one 1" ("一个一") , 即 11。 - * 11 被读作 "two 1s" ("两个一"), 即 21。 + * 11 被读作 "two 1" ("两个一"), 即 21。 * 21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。 * #TODO 迷迷糊糊 * @author liuchao @@ -16,8 +16,8 @@ public class CountAndSay { * @param n key * @return value */ - public String countAndSay(int n) { - StringBuffer result = new StringBuffer(); + private String countAndSay(int n) { + StringBuilder result = new StringBuilder(); String temp = ""; if (n == 1) { diff --git a/java/src/juejin/lc/leetCode/HammingWeight.java b/java/src/juejin/lc/leetCode/HammingWeight.java new file mode 100644 index 0000000..37b6b76 --- /dev/null +++ b/java/src/juejin/lc/leetCode/HammingWeight.java @@ -0,0 +1,21 @@ +package juejin.lc.leetCode; + +public class HammingWeight { + public int solution(int n){ + String str = Integer.toBinaryString(n); + int num = 0; + for (int i = 0; i < str.length(); i++) { + if (str.charAt(i) == '1'){ + ++num; + } + } + return num; + } + + public static void main(String[] args) { + int n = 521; + HammingWeight hammingWeight = new HammingWeight(); + int res = hammingWeight.solution(n); + System.out.println("res = " + res); + } +} diff --git a/java/src/juejin/lc/leetCode/IsHappy.java b/java/src/juejin/lc/leetCode/IsHappy.java index f997ce2..0375bf5 100644 --- a/java/src/juejin/lc/leetCode/IsHappy.java +++ b/java/src/juejin/lc/leetCode/IsHappy.java @@ -17,18 +17,40 @@ public class IsHappy { * 输入: 19 * 输出: true * 解释: - * 12 + 92 = 82 - * 82 + 22 = 68 - * 62 + 82 = 100 - * 12 + 02 + 02 = 1 + * 1^2 + 9^2 = 82 + * 8^2 + 2^2 = 68 + * 6^2 + 8^2 = 100 + * 1^2 + 0^2 + 0^2 = 1 * * @param n 快乐数 * @return 返回结果 */ private boolean solution(int n) { - return true; +// 快慢指针思想解决该问题,思路类似判断环 + int slow = n; + int fast = n; + do { + slow = recursion(slow); + fast = recursion(fast); + fast = recursion(fast); + }while (slow != fast); + return fast == 1; + } + + private int recursion(int n){ + int sum = 0; + while (n != 0){ + int num = n % 10; + sum += num * num; + n /= 10; + } + return sum; } public static void main(String[] args) { + int n = 2; + IsHappy isHappy = new IsHappy(); + boolean res = isHappy.solution(n); + System.out.println("res = " + res); } } From e77ab7ffdf82f1c17e4cb7e49aacc8fc57cfa6b2 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Thu, 7 Nov 2019 11:50:49 +0800 Subject: [PATCH 17/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B411=E6=9C=887=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/CountPrimes.java | 67 ++++++++++++ .../juejin/lc/leetCode/RemoveElements.java | 103 ++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/CountPrimes.java create mode 100644 java/src/juejin/lc/leetCode/RemoveElements.java diff --git a/java/src/juejin/lc/leetCode/CountPrimes.java b/java/src/juejin/lc/leetCode/CountPrimes.java new file mode 100644 index 0000000..4e9978e --- /dev/null +++ b/java/src/juejin/lc/leetCode/CountPrimes.java @@ -0,0 +1,67 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; + +public class CountPrimes { + /** + * 统计所有小于非负整数 n 的质数的数量。 + * + * 示例: + * + * 输入: 10 + * 输出: 4 + * 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。 + * @param n 输入 + * @return 输出 + */ + private int solution(int n) { + boolean[] isPrim = new boolean[n]; + // 将数组舒适化为true + Arrays.fill(isPrim, true); + + for (int i = 2; i * i < n; i++) { + if (isPrim[i]){ + for (int j = i * i; j < n; j+=i) { + System.out.println("j = " + j); + isPrim[j] = false; + } + } + } + int count = 0; + for (int i = 2; i 1; i--) { + boolean flag = true; + int j = 2; + for (; j < i; j++) { + if (i % j == 0) { + flag = false; + break; + } + if (j > Math.sqrt(i)) { + break; + } + } + System.out.println("j = " + j + ",flag = " + flag); + if (flag){ + ++num; + } + } + return num; + } + + public static void main(String[] args) { + CountPrimes countPrimes = new CountPrimes(); + int n = 10; + int res = countPrimes.solution(n); + System.out.println("res = " + res); + } +} diff --git a/java/src/juejin/lc/leetCode/RemoveElements.java b/java/src/juejin/lc/leetCode/RemoveElements.java new file mode 100644 index 0000000..8b1bd48 --- /dev/null +++ b/java/src/juejin/lc/leetCode/RemoveElements.java @@ -0,0 +1,103 @@ +package juejin.lc.leetCode; + +public class RemoveElements { + /** + * 删除链表中等于给定值 val 的所有节点。 + * + * 示例: + * + * 输入: 1->2->6->3->4->5->6, val = 6 + * 输出: 1->2->3->4->5 + * @param head 单链表 + * @param val 给定值 + * @return 输出链表 + */ + private ListNode solution(ListNode head, int val) { + //删除头结点时另做考虑(由于头结点没有前一个结点) + while (null != head && head.val == val){ + head = head.next; + } + if (null == head){ + return null; + } + ListNode node =head; + while (null != node.next) { + if (node.next.val == val){ + node.next = node.next.next; + }else { + node = node.next; + } + } + return head; + } + private ListNode solution2(ListNode head, int val){ + //创建一个虚拟头结点 + //随机传任意一个不等于val的值作为虚拟头结点 + ListNode dummyNode = new ListNode(val - 1); + dummyNode.next = head; + ListNode node = dummyNode; + while (null != node.next){ + if (node.next.val == val){ + node.next = node.next.next; + }else { + node = node.next; + } + } + return dummyNode.next; + } + private ListNode solution3(ListNode head, int val){ + // 递归 + if (null == head){ + return null; + } + head.next = solution3(head.next,val); + if (head.val == val){ + return head.next; + } + return head; + } + private static class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + private ListNode createNode(){ + ListNode node1 = new ListNode(1); + ListNode node2 = new ListNode(2); + ListNode node3 = new ListNode(6); + ListNode node4 = new ListNode(3); + ListNode node5 = new ListNode(4); + ListNode node6 = new ListNode(5); + ListNode node7 = new ListNode(6); + node1.next = node2; + node2.next = node3; + node3.next = node4; + node4.next = node5; + node5.next = node6; + node6.next = node7; + return node1; + } + private void print(ListNode listNode) { + while (null != listNode){ + int val = listNode.val; + System.out.print(val); + if (null != listNode.next){ + System.out.print("->"); + } + listNode = listNode.next; + } + System.out.println(); + } + public static void main(String[] args) { + RemoveElements removeElements = new RemoveElements(); + ListNode head = removeElements.createNode(); + removeElements.print(head); + int val = 6; + ListNode result = removeElements.solution(head,val); + ListNode result2 = removeElements.solution2(head,val); + ListNode result3 = removeElements.solution3(head,val); + removeElements.print(result); + removeElements.print(result2); + removeElements.print(result3); + } +} From a037fc788a0c9ed414ed9d3cece4e194e11b6af2 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Fri, 8 Nov 2019 18:23:25 +0800 Subject: [PATCH 18/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B411=E6=9C=888=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juejin/lc/leetCode/ContainsDuplicate.java | 49 +++++++++++++ .../lc/leetCode/ContainsNearbyDuplicate.java | 69 +++++++++++++++++++ java/src/juejin/lc/leetCode/CountPrimes.java | 24 ++++++- java/src/juejin/lc/leetCode/IsIsomorphic.java | 51 ++++++++++++++ java/src/juejin/lc/leetCode/ReverseList.java | 57 +++++++++++++++ 5 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 java/src/juejin/lc/leetCode/ContainsDuplicate.java create mode 100644 java/src/juejin/lc/leetCode/ContainsNearbyDuplicate.java create mode 100644 java/src/juejin/lc/leetCode/IsIsomorphic.java create mode 100644 java/src/juejin/lc/leetCode/ReverseList.java diff --git a/java/src/juejin/lc/leetCode/ContainsDuplicate.java b/java/src/juejin/lc/leetCode/ContainsDuplicate.java new file mode 100644 index 0000000..1c55aa5 --- /dev/null +++ b/java/src/juejin/lc/leetCode/ContainsDuplicate.java @@ -0,0 +1,49 @@ +package juejin.lc.leetCode; + +import java.util.HashMap; +import java.util.Map; + +/** + * 存在重复元素 + */ +public class ContainsDuplicate { + /** + * 给定一个整数数组,判断是否存在重复元素。 + *

+ * 如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。 + *

+ * 示例 1: + *

+ * 输入: [1,2,3,1] + * 输出: true + * 示例 2: + *

+ * 输入: [1,2,3,4] + * 输出: false + * 示例 3: + *

+ * 输入: [1,1,1,3,3,4,3,2,4,2] + * 输出: true + * + * @param nums 数组 + * @return 返回结果 + */ + private boolean solution(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + if (map.containsKey(num)) { + return true; + } else { + map.put(num, 0); + } + } + return false; + } + + public static void main(String[] args) { + ContainsDuplicate containsDuplicate = new ContainsDuplicate(); + int[] nums = {1, 1, 1, 3, 3, 4, 3, 2, 4, 2}; + boolean result = containsDuplicate.solution(nums); + System.out.println("result = " + result); + } +} diff --git a/java/src/juejin/lc/leetCode/ContainsNearbyDuplicate.java b/java/src/juejin/lc/leetCode/ContainsNearbyDuplicate.java new file mode 100644 index 0000000..38581fd --- /dev/null +++ b/java/src/juejin/lc/leetCode/ContainsNearbyDuplicate.java @@ -0,0 +1,69 @@ +package juejin.lc.leetCode; + +import java.util.HashSet; +import java.util.Set; + +/** + * 存在重复元素II + */ +public class ContainsNearbyDuplicate { + /** + * 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j, + * 使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。 + *

+ * 示例 1: + *

+ * 输入: nums = [1,2,3,1], k = 3 + * 输出: true + * 示例 2: + *

+ * 输入: nums = [1,0,1,1], k = 1 + * 输出: true + * 示例 3: + *

+ * 输入: nums = [1,2,3,1,2,3], k = 2 + * 输出: false + * + * @param nums 数组 + * @param k 绝对差值 + * @return 返回结果 + */ + private boolean solution(int[] nums, int k) { + Set set = new HashSet<>(); + for (int i = 0; i < nums.length; i++) { + if (set.contains(nums[i])) { + return true; + } + set.add(nums[i]); + System.out.println("size = " + set.size() + ",k = " + k); + if (set.size() > k) { + System.out.println("nums[" + i + " - " + k + "] = " + nums[i - k]); + set.remove(nums[i - k]); + } + System.out.println("set = " + set.toString()); + } + return false; + } + + private boolean solution1(int[] nums, int k) { + if (nums.length == 0) { + return false; + } + for (int i = 0; i < nums.length; i++) { + for (int j = 1; j <= k; j++) { + if (i + j < nums.length && nums[i] == nums[i + j]) { + return true; + } + } + } + return false; + } + + public static void main(String[] args) { + ContainsNearbyDuplicate containsNearbyDuplicate = new ContainsNearbyDuplicate(); + int[] nums = {1,0,1,1}; + int k = 3; + boolean result = containsNearbyDuplicate.solution(nums, k); + System.out.println("result = " + result); + } +} diff --git a/java/src/juejin/lc/leetCode/CountPrimes.java b/java/src/juejin/lc/leetCode/CountPrimes.java index 4e9978e..bbda844 100644 --- a/java/src/juejin/lc/leetCode/CountPrimes.java +++ b/java/src/juejin/lc/leetCode/CountPrimes.java @@ -16,7 +16,7 @@ public class CountPrimes { */ private int solution(int n) { boolean[] isPrim = new boolean[n]; - // 将数组舒适化为true + // 将数组初始化为true Arrays.fill(isPrim, true); for (int i = 2; i * i < n; i++) { @@ -35,6 +35,26 @@ private int solution(int n) { } return count; } + private int solution2(int n) { + boolean[] isPrim = new boolean[n]; + Arrays.fill(isPrim, true); + // 将 i的倍数全部剔除,提高for效率 + for (int i = 2; i < n; i++) { + if (isPrim[i]){ + for (int j = i * 2; j < n; j+=i) { + System.out.println("j = " + j); + isPrim[j] = false; + } + } + } + int count = 0; + for (int i = 2; i "); + } + listNode = listNode.next; + } + System.out.println(); + } + public static void main(String[] args) { + ReverseList reverseList = new ReverseList(); + ListNode head = reverseList.createNode(); + reverseList.print(head); + ListNode resNode = reverseList.solution(head); + reverseList.print(resNode); + } +} From c3aecb348c3bf2f9a3531ac4ddf98a2fc54a5b39 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Wed, 13 Nov 2019 09:40:36 +0800 Subject: [PATCH 19/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B411=E6=9C=8813=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/InvertTree.java | 82 +++++++++++++++++++ java/src/juejin/lc/leetCode/IsPowerOfTwo.java | 38 +++++++++ java/src/juejin/lc/leetCode/MyStack.java | 60 ++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/InvertTree.java create mode 100644 java/src/juejin/lc/leetCode/IsPowerOfTwo.java create mode 100644 java/src/juejin/lc/leetCode/MyStack.java diff --git a/java/src/juejin/lc/leetCode/InvertTree.java b/java/src/juejin/lc/leetCode/InvertTree.java new file mode 100644 index 0000000..642c0dc --- /dev/null +++ b/java/src/juejin/lc/leetCode/InvertTree.java @@ -0,0 +1,82 @@ +package juejin.lc.leetCode; + +/** + * 备注: + * 这个问题是受到 Max Howell 的 原问题 启发的 : + * 谷歌:我们90%的工程师使用您编写的软件(Homebrew), + * 但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。 + */ +public class InvertTree { + /** + * 翻转一棵二叉树。 + * + * 示例: + * + * 输入: + * + * 4 + * / \ + * 2 7 + * / \ / \ + * 1 3 6 9 + * 输出: + * + * 4 + * / \ + * 7 2 + * / \ / \ + * 9 6 3 1 + * + * @param root 二叉树 + * @return 反转后的二叉树 + */ + private TreeNode solution(TreeNode root) { + if (root == null) { + return null; + } + TreeNode left = solution(root.left); + root.left = solution(root.right); + root.right = left; + return root; + } + private TreeNode createTreeNode(){ + TreeNode treeNode = new TreeNode(4); + TreeNode treeNode1 = new TreeNode(2); + TreeNode treeNode2 = new TreeNode(7); + treeNode.left = treeNode1; + treeNode.right = treeNode2; + TreeNode treeNode3 = new TreeNode(1); + TreeNode treeNode4 = new TreeNode(3); + treeNode1.left = treeNode3; + treeNode1.right = treeNode4; + TreeNode treeNode5 = new TreeNode(6); + TreeNode treeNode6 = new TreeNode(9); + treeNode2.left = treeNode5; + treeNode2.right = treeNode6; + return treeNode; + } + private void preOrderTraversal(TreeNode tree) { + if (null == tree){ + return; + } + System.out.print(tree.val + " "); + preOrderTraversal(tree.left); + preOrderTraversal(tree.right); + } + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) { + InvertTree invertTree = new InvertTree(); + TreeNode treeNode = invertTree.createTreeNode(); + invertTree.preOrderTraversal(treeNode); + System.out.println(); + TreeNode node = invertTree.createTreeNode(); + TreeNode result = invertTree.solution(node); + invertTree.preOrderTraversal(result); + } +} diff --git a/java/src/juejin/lc/leetCode/IsPowerOfTwo.java b/java/src/juejin/lc/leetCode/IsPowerOfTwo.java new file mode 100644 index 0000000..85cba95 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsPowerOfTwo.java @@ -0,0 +1,38 @@ +package juejin.lc.leetCode; + +public class IsPowerOfTwo { + /** + * 给定一个整数,编写一个函数来判断它是否是 2 的幂次方。 + * + * 示例 1: + * + * 输入: 1 + * 输出: true + * 解释: 20 = 1 + * 示例 2: + * + * 输入: 16 + * 输出: true + * 解释: 24 = 16 + * 示例 3: + * + * 输入: 218 + * 输出: false + * + * @param n 指定整数 + * @return 是否是2的幂次方 + */ + private boolean solution(int n){ +// 若 n = 2^x +// x且 x 为自然数(即 n 为 2 的幂),则一定满足以下条件: +// 恒有 n & (n - 1) == 0,这是因为: +// nn 二进制最高位为 1,其余所有位为 0; +// n - 1 二进制最高位为 0,其余所有位为 1; +// 一定满足 n > 0。 +// 因此,通过 n > 0 且 n & (n - 1) == 0 即可判定是否满足 n = 2^x + return n > 0 && (n & (n - 1)) == 0; + } + private boolean solution1(int n){ + return n > 0 && (n & -n) == n; + } +} diff --git a/java/src/juejin/lc/leetCode/MyStack.java b/java/src/juejin/lc/leetCode/MyStack.java new file mode 100644 index 0000000..073250b --- /dev/null +++ b/java/src/juejin/lc/leetCode/MyStack.java @@ -0,0 +1,60 @@ +package juejin.lc.leetCode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Your MyStack object will be instantiated and called as such: + * MyStack obj = new MyStack(); + * obj.push(x); + * int param_2 = obj.pop(); + * int param_3 = obj.top(); + * boolean param_4 = obj.empty(); + */ +public class MyStack { + + private Queue queue; + /** Initialize your data structure here. */ + private MyStack() { + queue = new LinkedList<>(); + } + + /** Push element x onto stack. */ + private void push(int x) { + queue.add(x); + int size = queue.size(); + while (size > 1) { + queue.add(queue.remove()); + --size; + } + } + + /** Removes the element on top of the stack and returns that element. */ + private int pop() { + Integer num = queue.poll(); + return null == num ? -1 : num; + } + + /** Get the top element. */ + private int top() { + Integer num = queue.peek(); + return null == num ? -1 : num; + } + + /** Returns whether the stack is empty. */ + private boolean empty() { + return queue.isEmpty(); + } + + public static void main(String[] args) { + MyStack myStack = new MyStack(); + myStack.push(1); + myStack.push(2); + int param_2 = myStack.pop(); + System.out.println("param_2 = " + param_2); + int param_3 = myStack.top(); + System.out.println("param_3 = " + param_3); + boolean param_4 = myStack.empty(); + System.out.println("param_4 = " + param_4); + } +} From 269e5bec1de5f89c3693cfaac24d959aaa843500 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Fri, 15 Nov 2019 18:44:53 +0800 Subject: [PATCH 20/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B411=E6=9C=8815=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lc/leetCode/IowestCommonAncestor.java | 71 +++++++++++++++++++ java/src/juejin/lc/leetCode/MyQueue.java | 55 ++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/IowestCommonAncestor.java create mode 100644 java/src/juejin/lc/leetCode/MyQueue.java diff --git a/java/src/juejin/lc/leetCode/IowestCommonAncestor.java b/java/src/juejin/lc/leetCode/IowestCommonAncestor.java new file mode 100644 index 0000000..ce8e177 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IowestCommonAncestor.java @@ -0,0 +1,71 @@ +package juejin.lc.leetCode; + +public class IowestCommonAncestor { + /** + * 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 + * + * 百度百科中最近公共祖先的定义为: + * “对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大 + * (一个节点也可以是它自己的祖先)。” + * 例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5] + * + * 示例 1: + * + * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 + * 输出: 6 + * 解释: 节点 2 和节点 8 的最近公共祖先是 6。 + * 示例 2: + * + * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 + * 输出: 2 + * 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。 + *   + * + * 说明: + * + * 所有节点的值都是唯一的。 + * p、q 为不同节点且均存在于给定的二叉搜索树中。 + * + * @param root 二叉树 + * @param p 二叉树子节点 + * @param q 二叉树子节点 + * @return 节点树 + */ + public TreeNode solution(TreeNode root, TreeNode p, TreeNode q) { + int rootVal = root.val; + int pVal = p.val; + int qVal = q.val; + if (pVal > rootVal && qVal > rootVal) { + return solution(root.right,p,q); + }else if(pVal < rootVal && qVal < rootVal) { + return solution(root.left,p,q); + } + return root; + } + public TreeNode solution1(TreeNode root, TreeNode p, TreeNode q) { + int pVal = p.val; + int qVal = q.val; + TreeNode node = root; + while (null != node) { + int rootVal = node.val; + if (pVal > rootVal && qVal > rootVal) { + node = node.right; + }else if(pVal < rootVal && qVal < rootVal) { + node = node.left; + }else { + return node; + } + } + return node; + } + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) { + + } +} diff --git a/java/src/juejin/lc/leetCode/MyQueue.java b/java/src/juejin/lc/leetCode/MyQueue.java new file mode 100644 index 0000000..791d730 --- /dev/null +++ b/java/src/juejin/lc/leetCode/MyQueue.java @@ -0,0 +1,55 @@ +package juejin.lc.leetCode; + +import java.util.Stack; + +public class MyQueue { + private Stack stack; + private Stack baseStack; + /** Initialize your data structure here. */ + private MyQueue() { + stack = new Stack<>(); + baseStack = new Stack<>(); + } + + /** Push element x to the back of queue. */ + private void push(int x) { + System.out.println(stack.toString()); + while (!stack.empty()) { + baseStack.push(stack.pop()); + } + baseStack.push(x); + while (!baseStack.empty()) { + stack.push(baseStack.pop()); + } + + } + + /** Removes the element from in front of queue and returns that element. */ + private int pop() { + Integer num = stack.pop(); + return null == num ? -1 : num; + } + + /** Get the front element. */ + private int peek() { + Integer num = stack.peek(); + return null == num ? -1 : num; + } + + /** Returns whether the queue is empty. */ + private boolean empty() { + return stack.empty() && baseStack.empty(); + } + + public static void main(String[] args) { + MyQueue myQueue = new MyQueue(); + myQueue.push(1); + myQueue.push(2); + int param_2 = myQueue.pop(); + System.out.println("param_2 = " + param_2); + int param_3 = myQueue.peek(); + System.out.println("param_3 = " + param_3); + boolean param_4 = myQueue.empty(); + System.out.println("param_4 = " + param_4); + } +} From 27e4b2b6630b05fa5bd4064f02f2ad5b6662e1eb Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Tue, 19 Nov 2019 09:31:57 +0800 Subject: [PATCH 21/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B411=E6=9C=8819=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/DeleteNode.java | 94 +++++++++++++++++++++ java/src/juejin/lc/leetCode/IsAnagram.java | 82 ++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/DeleteNode.java create mode 100644 java/src/juejin/lc/leetCode/IsAnagram.java diff --git a/java/src/juejin/lc/leetCode/DeleteNode.java b/java/src/juejin/lc/leetCode/DeleteNode.java new file mode 100644 index 0000000..42d57b8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/DeleteNode.java @@ -0,0 +1,94 @@ +package juejin.lc.leetCode; + +/** + * 删除链表中的节点 + */ +public class DeleteNode { + private ListNode head; + /** + * 请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。 + * + * 示例 1: + * + * 输入: head = [4,5,1,9], node = 5 + * 输出: [4,1,9] + * 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. + * 示例 2: + * + * 输入: head = [4,5,1,9], node = 1 + * 输出: [4,5,9] + * 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9. + *   + * 说明: + * + * 链表至少包含两个节点。 + * 链表中所有节点的值都是唯一的。 + * 给定的节点为非末尾节点并且一定是链表中的一个有效节点。 + * 不要从你的函数中返回任何结果。 + + * @param node 节点 + */ + private void solution(ListNode node) { + node.val = node.next.val; + node.next = node.next.next; + } + + /** + * 常规删除链表指定节点,与题目无关 + * @param node 节点 + */ + private void solution1(ListNode node) { + ListNode headNode = head; + if (headNode.val == node.val){ + headNode = headNode.next; + } + while (null != headNode.next && null != headNode.next.next){ + if (headNode.next.val == node.val){ + headNode.next = headNode.next.next; + }else { + headNode = headNode.next; + } + } + } + public class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + private ListNode createHead(){ + ListNode node1 = new ListNode(4); + ListNode node2 = new ListNode(5); + ListNode node3 = new ListNode(1); + ListNode node4 = new ListNode(9); + node1.next = node2; + node2.next = node3; + node3.next = node4; + return node1; + } + private ListNode createNode(){ + ListNode node3 = new ListNode(1); + ListNode node4 = new ListNode(9); + node3.next = node4; + return node3; + } + private void print() { + ListNode listNode = head; + while (null != listNode){ + int val = listNode.val; + System.out.print(val); + if (null != listNode.next){ + System.out.print("->"); + } + listNode = listNode.next; + } + System.out.println(); + } + public static void main(String[] args) { + DeleteNode deleteNode = new DeleteNode(); + deleteNode.head = deleteNode.createHead(); + deleteNode.print(); + ListNode node = deleteNode.createNode(); + deleteNode.solution(node); + deleteNode.print(); + } +} diff --git a/java/src/juejin/lc/leetCode/IsAnagram.java b/java/src/juejin/lc/leetCode/IsAnagram.java new file mode 100644 index 0000000..676b52f --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsAnagram.java @@ -0,0 +1,82 @@ +package juejin.lc.leetCode; + +import juejin.lc.arithmetic.Array; + +import java.util.Arrays; + +public class IsAnagram { + /** + * 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 + * + * 示例 1: + * + * 输入: s = "anagram", t = "nagaram" + * 输出: true + * 示例 2: + * + * 输入: s = "rat", t = "car" + * 输出: false + * 说明: + * 你可以假设字符串只包含小写字母。 + * + * @param s 字符串 + * @param t 字符串 + * @return r + */ + private boolean solution(String s, String t) { + if (s.length() != t.length()) { + return false; + } + char[] s1 = s.toCharArray(); + char[] t1 = t.toCharArray(); + Arrays.sort(s1); + Arrays.sort(t1); + return Arrays.equals(s1,t1); + } + + /** + * 高阶解法 + * @param s 字符串 + * @param t 字符串 + * @return r + */ + private boolean solution1(String s, String t) { + if(s.length() != t.length()){ + return false; + } + int[] counter = new int[26]; + for (int i = 0; i < s.length(); i++) { + ++counter[s.charAt(i) - 'a']; + --counter[t.charAt(i) - 'a']; + } + for (int count: counter) { + if (count != 0) { + return false; + } + } + return true; + } + private boolean solution2(String s, String t) { + if(s.length() != t.length()){ + return false; + } + int[] table = new int[26]; + for (int i = 0; i < s.length(); i++) { + ++table[s.charAt(i) - 'a']; + } + for (int i = 0; i < t.length(); i++) { + --table[t.charAt(i) - 'a']; + if (table[t.charAt(i) - 'a'] < 0) { + return false; + } + } + return true; + } + public static void main(String[] args) { + IsAnagram isAnagram = new IsAnagram(); + String s = "anagram"; + String t = "nagram"; + boolean result = isAnagram.solution(s,t); + System.out.println("result = " + result); + } +} From 2e17fe79758f26aaea6ff233aae7d012ff28d92b Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Thu, 5 Dec 2019 15:04:52 +0800 Subject: [PATCH 22/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B412=E6=9C=885=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/AddDigits.java | 40 ++++++++++++ .../juejin/lc/leetCode/BinaryTreePaths.java | 64 +++++++++++++++++++ java/src/juejin/lc/leetCode/IsUgly.java | 55 ++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/AddDigits.java create mode 100644 java/src/juejin/lc/leetCode/BinaryTreePaths.java create mode 100644 java/src/juejin/lc/leetCode/IsUgly.java diff --git a/java/src/juejin/lc/leetCode/AddDigits.java b/java/src/juejin/lc/leetCode/AddDigits.java new file mode 100644 index 0000000..74f035c --- /dev/null +++ b/java/src/juejin/lc/leetCode/AddDigits.java @@ -0,0 +1,40 @@ +package juejin.lc.leetCode; + +public class AddDigits { + /** + * 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。 + * + * 示例: + * + * 输入: 38 + * 输出: 2 + * 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。 + * 进阶: + * 你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗? + * + * @param num 非负整数 + * @return 个位数结果 + */ + private int solution(int num) { + int sum = 0; + while (num > 9) { + sum += num % 10; + num = num / 10; + } + sum += num; + if (sum > 9) { + return solution(sum); + } + return sum; + } + private int optimalSolution(int num) { + return (num - 1) % 9 + 1; + } + + public static void main(String[] args) { + int num = 10; + AddDigits addDigits = new AddDigits(); + int result = addDigits.solution(num); + System.out.println("result = " + result); + } +} diff --git a/java/src/juejin/lc/leetCode/BinaryTreePaths.java b/java/src/juejin/lc/leetCode/BinaryTreePaths.java new file mode 100644 index 0000000..66c2ee6 --- /dev/null +++ b/java/src/juejin/lc/leetCode/BinaryTreePaths.java @@ -0,0 +1,64 @@ +package juejin.lc.leetCode; + +import java.util.LinkedList; +import java.util.List; + +public class BinaryTreePaths { + /** + * 给定一个二叉树,返回所有从根节点到叶子节点的路径。 + * 说明: 叶子节点是指没有子节点的节点。 + * 示例: + * 输入: + * + * 1 + * / \ + * 2 3 + * \ + * 5 + * 输出: ["1->2->5", "1->3"] + * 解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3 + * @param root 二叉树 + * @return 二叉树的所有路径 + */ + private List solution(TreeNode root) { + LinkedList paths = new LinkedList<>(); + constructPaths(root, "", paths); + return paths; + } + + private void constructPaths(TreeNode root, String path, LinkedList paths) { + if (null != root){ + path += Integer.toString(root.val); + if (null == root.left && null == root.right){ + paths.add(path); + }else { + path += "->"; + constructPaths(root.left, path, paths); + constructPaths(root.right, path, paths); + } + } + } + private TreeNode createTreeNode(){ + TreeNode node = new TreeNode(1); + TreeNode node1 = new TreeNode(2); + TreeNode node2 = new TreeNode(3); + node.left = node1; + node.right = node2; + node1.right = new TreeNode(5); + return node; + } + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + public static void main(String[] args) { + BinaryTreePaths binaryTreePaths = new BinaryTreePaths(); + TreeNode root = binaryTreePaths.createTreeNode(); + List list = binaryTreePaths.solution(root); + System.out.println(list.toString()); + } + +} diff --git a/java/src/juejin/lc/leetCode/IsUgly.java b/java/src/juejin/lc/leetCode/IsUgly.java new file mode 100644 index 0000000..31db1c9 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsUgly.java @@ -0,0 +1,55 @@ +package juejin.lc.leetCode; + +public class IsUgly { + /** + * 判断给定的数是否为丑数。 + * + * 丑数就是只包含质因数 2, 3, 5 的正整数。 + * + * 示例 1: + * + * 输入: 6 + * 输出: true + * 解释: 6 = 2 × 3 + * 示例 2: + * + * 输入: 8 + * 输出: true + * 解释: 8 = 2 × 2 × 2 + * 示例 3: + * + * 输入: 14 + * 输出: false + * 解释: 14 不是丑数,因为它包含了另外一个质因数 7。 + * 说明: + * + * 1 是丑数。 + * 输入不会超过 32 位有符号整数的范围: [−2^31,  2^31 − 1]。 + * @param num 数 + * @return 返回结果 + */ + private boolean solution(int num) { + if (num <= 1) { + return num == 1; + } + while (num != 1) { + if (num % 2 == 0) { + num /= 2; + } else if (num % 3 == 0) { + num /= 3; + } else if (num % 5 == 0) { + num /= 5; + } else { + return false; + } + } + return true; + } + + public static void main(String[] args) { + int num = 6; + IsUgly isUgly = new IsUgly(); + boolean result = isUgly.solution(num); + System.out.println("result = " + result); + } +} From f80f6310992c949d8c4cf766762f30dbe1a560ab Mon Sep 17 00:00:00 2001 From: liuchao <43998324+chaoaiqi@users.noreply.github.com> Date: Thu, 5 Dec 2019 18:16:08 +0800 Subject: [PATCH 23/43] Set theme jekyll-theme-tactile --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..259a24e --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-tactile \ No newline at end of file From e122d6ef0af038d90a280d92569ef026bfd79b17 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Tue, 10 Dec 2019 09:43:27 +0800 Subject: [PATCH 24/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B412=E6=9C=8810=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/juejin/lc/leetCode/MissingNumber.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/MissingNumber.java diff --git a/java/src/juejin/lc/leetCode/MissingNumber.java b/java/src/juejin/lc/leetCode/MissingNumber.java new file mode 100644 index 0000000..dbac082 --- /dev/null +++ b/java/src/juejin/lc/leetCode/MissingNumber.java @@ -0,0 +1,81 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class MissingNumber { + /** + * 给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。 + *

+ * 示例 1: + *

+ * 输入: [3,0,1] + * 输出: 2 + * 示例 2: + *

+ * 输入: [9,6,4,2,3,5,7,0,1] + * 输出: 8 + * + * @param nums 给定正整数数组 + * @return 返回缺失值 + */ + private int solution(int[] nums) { + int missing = nums.length; + for (int i = 0; i < nums.length; i++) { + System.out.println(i + "^" + nums[i] + " = " + (i ^ nums[i])); + System.out.println(missing + "^" + i + "^" + nums[i] + " = " + (missing ^ i ^ nums[i])); + missing ^= i ^ nums[i]; + } + return missing; + } + + /** + * 使用一个set存储 + * + * @param nums 给定正整数数组 + * @return 返回缺失值 + */ + private int solution2(int[] nums) { + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + for (int i = 0; i < nums.length + 1; i++) { + if (!set.contains(i)) { + return i; + } + } + return -1; + } + + /** + * 常规思路 + * + * @param nums 给定正整数数组 + * @return 返回缺失值 + */ + private int solution1(int[] nums) { + Arrays.sort(nums); + if (nums[nums.length - 1] != nums.length) { + return nums.length; + } else if (nums[0] != 0) { + return 0; + } + for (int i = 1; i < nums.length; i++) { + int extraNum = nums[i - 1] + 1; + if (nums[i] != extraNum) { + return extraNum; + } + } + return -1; + } + + public static void main(String[] args) { + MissingNumber missingNumber = new MissingNumber(); + int[] nums = {0,1}; +// int[] nums = {9, 6, 4, 2, 3, 5, 7, 0, 1}; + int result = missingNumber.solution2(nums); + System.out.println("result = " + result); + } +} From 49c2b4b5f452c4f464f4ce683ccd30a5e62ff38d Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Fri, 13 Dec 2019 15:39:36 +0800 Subject: [PATCH 25/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B412=E6=9C=8813=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juejin/lc/leetCode/FirstBadVersion.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/FirstBadVersion.java diff --git a/java/src/juejin/lc/leetCode/FirstBadVersion.java b/java/src/juejin/lc/leetCode/FirstBadVersion.java new file mode 100644 index 0000000..956e4dc --- /dev/null +++ b/java/src/juejin/lc/leetCode/FirstBadVersion.java @@ -0,0 +1,54 @@ +package juejin.lc.leetCode; + +public class FirstBadVersion { + /** + * 你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。 + * 由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。 + *

+ * 假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。 + *

+ * 你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。 + * 实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。 + *

+ * 示例: + *

+ * 给定 n = 5,并且 version = 4 是第一个错误的版本。 + *

+ * 调用 isBadVersion(3) -> false + * 调用 isBadVersion(5) -> true + * 调用 isBadVersion(4) -> true + *

+ * 所以,4 是第一个错误的版本。 + * + * @param n 最新版本号 + * @return 第一个错误的版本 + */ + private int solution(int n) { + // 尽量减少调用api的次数,实际上就是二分法的变体 + int left = 1; + int right = n; + while (left < right) { + int mid = left + (right - left) / 2; + if (isBadVersion(mid)){ + right = mid; + }else { + left = mid + 1; + } + } + return left; + } + + private static final int VERSION = 2; + + private boolean isBadVersion(int n) { + System.out.println("调用api..." + n); + return n >= VERSION; + } + + public static void main(String[] args) { + FirstBadVersion firstBadVersion = new FirstBadVersion(); + int n = 3; + int result = firstBadVersion.solution(n); + System.out.println("result === " + result); + } +} From d399236aaf728272f7f4ef64e1f6efc0d02174fc Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Wed, 18 Dec 2019 15:32:02 +0800 Subject: [PATCH 26/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B412=E6=9C=8818=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/MoveZeroes.java | 64 +++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/MoveZeroes.java diff --git a/java/src/juejin/lc/leetCode/MoveZeroes.java b/java/src/juejin/lc/leetCode/MoveZeroes.java new file mode 100644 index 0000000..5b230e8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/MoveZeroes.java @@ -0,0 +1,64 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; + +public class MoveZeroes { + /** + * 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 + *

+ * 示例: + *

+ * 输入: [0,1,0,3,12] + * 输出: [1,3,12,0,0] + * 说明: + *

+ * 必须在原数组上操作,不能拷贝额外的数组。 + * 尽量减少操作次数。 + * + * @param nums 数组 + */ + private void solution(int[] nums) { + int index = 0; + for (int num : nums) { + if (num != 0) { + nums[index++] = num; + } + } + while (index < nums.length) { + nums[index++] = 0; + } + } + + + private void solution2(int[] nums) { + int count = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] != 0) { + nums[count++] = nums[i]; + } + } + for (int i = count; i < nums.length; i++) { + nums[i] = 0; + } + } + + private void solution1(int[] nums) { + int count = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i - count] == 0) { + for (int j = i - count + 1; j < nums.length - count; j++) { + nums[j - 1] = nums[j]; + } + ++count; + nums[nums.length - count] = 0; + } + } + } + + public static void main(String[] args) { + MoveZeroes moveZeroes = new MoveZeroes(); + int[] nums = {0, 1, 0, 3, 12}; + moveZeroes.solution(nums); + System.out.println("nums = " + Arrays.toString(nums)); + } +} From ab66ebe624e99f9bd483a0047f6507be7d641b12 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Thu, 19 Dec 2019 09:47:29 +0800 Subject: [PATCH 27/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B412=E6=9C=8819=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/WordPattern.java | 62 ++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/WordPattern.java diff --git a/java/src/juejin/lc/leetCode/WordPattern.java b/java/src/juejin/lc/leetCode/WordPattern.java new file mode 100644 index 0000000..fdd0de6 --- /dev/null +++ b/java/src/juejin/lc/leetCode/WordPattern.java @@ -0,0 +1,62 @@ +package juejin.lc.leetCode; + +import java.util.HashMap; +import java.util.Map; + +public class WordPattern { + /** + * 给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。 + *

+ * 这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。 + *

+ * 示例1: + *

+ * 输入: pattern = "abba", str = "dog cat cat dog" + * 输出: true + * 示例 2: + *

+ * 输入:pattern = "abba", str = "dog cat cat fish" + * 输出: false + * 示例 3: + *

+ * 输入: pattern = "aaaa", str = "dog cat cat dog" + * 输出: false + * 示例 4: + *

+ * 输入: pattern = "abba", str = "dog dog dog dog" + * 输出: false + * 说明: + * 你可以假设 pattern 只包含小写字母, str 包含了由单个空格分隔的小写字母。     + * + * @param pattern 规则 + * @param str 字符串 + * @return 是否匹配 + */ + private boolean solution(String pattern, String str) { + String[] strs = str.split(" "); + char[] chars = pattern.toCharArray(); + Map map = new HashMap<>(strs.length); + if (strs.length != chars.length) { + return false; + } + for (int i = 0; i < strs.length; i++) { + if (!map.containsKey(chars[i]) && !map.containsValue(strs[i])) { + map.put(chars[i], strs[i]); + } else { + String value = map.get(chars[i]); + if (!strs[i].equals(value) || "".equals(value)) { + return false; + } + } + } + return true; + } + + public static void main(String[] args) { + String pattern = "abba"; + String str = "dog dog dog dog"; + WordPattern wordPattern = new WordPattern(); + boolean result = wordPattern.solution(pattern, str); + System.out.println("result = " + result); + } +} From 625988f291dfb3ca4b73125d5d351d1dfabe73c3 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Mon, 23 Dec 2019 18:37:51 +0800 Subject: [PATCH 28/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0=202019=E5=B9=B412=E6=9C=8823=E6=97=A518:37:4?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- java/src/juejin/lc/leetCode/CanWinNim.java | 39 ++++++++++++++ java/src/juejin/lc/leetCode/GetHint.java | 62 ++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 java/src/juejin/lc/leetCode/CanWinNim.java create mode 100644 java/src/juejin/lc/leetCode/GetHint.java diff --git a/.gitignore b/.gitignore index b32f71b..36b48e4 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,7 @@ hs_err_pid* .project .settings .classpath - +/out /java/bin/.gitignore *.idea diff --git a/java/src/juejin/lc/leetCode/CanWinNim.java b/java/src/juejin/lc/leetCode/CanWinNim.java new file mode 100644 index 0000000..ddb8a45 --- /dev/null +++ b/java/src/juejin/lc/leetCode/CanWinNim.java @@ -0,0 +1,39 @@ +package juejin.lc.leetCode; + +public class CanWinNim { + /** + * 你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 + * 拿掉最后一块石头的人就是获胜者。你作为先手。 + * + * 你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。 + * + * 示例: + * + * 输入: 4 + * 输出: false + * 解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛; + * 因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。 + * + * @param n 石头数量 + * @return 是否赢得比赛 + */ + private boolean solution(int n) { + //让我们考虑一些小例子。显而易见的是,如果石头堆中只有一块、两块、或是三块石头, + // 那么在你的回合,你就可以把全部石子拿走,从而在游戏中取胜。而如果就像题目描述那样, + // 堆中恰好有四块石头,你就会失败。因为在这种情况下不管你取走多少石头,总会为你的对手留下几块, + // 使得他可以在游戏中打败你。因此,要想获胜,在你的回合中,必须避免石头堆中的石子数为 4 的情况。 + //同样地,如果有五块、六块、或是七块石头,你可以控制自己拿取的石头数,总是恰好给你的对手留下四块石头, + // 使他输掉这场比赛。但是如果石头堆里有八块石头,你就不可避免地会输掉, + // 因为不管你从一堆石头中挑出一块、两块还是三块,你的对手都可以选择三块、两块或一块, + // 以确保在再一次轮到你的时候,你会面对四块石头。 + //显然,它以相同的模式不断重复 n=4,8,12,16,,,,基本可以看出是 4 的倍数。 + return (n % 4 != 0); + } + + public static void main(String[] args) { + CanWinNim canWinNim = new CanWinNim(); + int n = 100; + boolean result = canWinNim.solution(n); + System.out.println("result = " + result); + } +} diff --git a/java/src/juejin/lc/leetCode/GetHint.java b/java/src/juejin/lc/leetCode/GetHint.java new file mode 100644 index 0000000..1e2e772 --- /dev/null +++ b/java/src/juejin/lc/leetCode/GetHint.java @@ -0,0 +1,62 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.List; + +public class GetHint { + /** + * 你正在和你的朋友玩 猜数字(Bulls and Cows)游戏:你写下一个数字让你的朋友猜。 + * 每次他猜测后,你给他一个提示,告诉他有多少位数字和确切位置都猜对了(称为“Bulls”, 公牛), + * 有多少位数字猜对了但是位置不对(称为“Cows”, 奶牛)。 + * 你的朋友将会根据提示继续猜,直到猜出秘密数字。 + *

+ * 请写出一个根据秘密数字和朋友的猜测数返回提示的函数,用 A 表示公牛,用 B 表示奶牛。 + *

+ * 请注意秘密数字和朋友的猜测数都可能含有重复数字。 + * 示例 1: + * 输入: secret = "1807", guess = "7810" + * 输出: "1A3B" + * 解释: 1 公牛和 3 奶牛。公牛是 8,奶牛是 0, 1 和 7。 + *

+ * 示例 2: + * 输入: secret = "1123", guess = "0111" + * 输出: "1A1B" + * 解释: 朋友猜测数中的第一个 1 是公牛,第二个或第三个 1 可被视为奶牛。 + * + * @param secret 秘密数字 + * @param guess 猜测数 + * @return 返回结果 + */ + private String solution(String secret, String guess) { + int bullsCount = 0; + int cowsCount = 0; + char[] secretArrs = secret.toCharArray(); + char[] guessArrs = guess.toCharArray(); + List secretList = new ArrayList<>(); + List guessList = new ArrayList<>(); + // 先判断 A + for (int i = 0; i < secretArrs.length; i++) { + if (secretArrs[i] == guessArrs[i]) { + ++bullsCount; + } else { + secretList.add(secretArrs[i]); + guessList.add(guessArrs[i]); + } + } + for (Character c : guessList) { + if (secretList.contains(c)) { + ++cowsCount; + secretList.remove(c); + } + } + return bullsCount + "A" + cowsCount + "B"; + } + + public static void main(String[] args) { + GetHint getHint = new GetHint(); + String secret = "11"; + String guess = "10"; + String result = getHint.solution(secret, guess); + System.out.println("result = " + result); + } +} From 3fb43eaaffbaf95c4e631357a9567907818cb2b0 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Wed, 25 Dec 2019 10:57:44 +0800 Subject: [PATCH 29/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0=202019=E5=B9=B412=E6=9C=8825=E6=97=A510:57:3?= =?UTF-8?q?4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juejin/lc/leetCode/IsPowerOfThree.java | 54 +++++++++++++++++ java/src/juejin/lc/leetCode/NumArray.java | 58 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/IsPowerOfThree.java create mode 100644 java/src/juejin/lc/leetCode/NumArray.java diff --git a/java/src/juejin/lc/leetCode/IsPowerOfThree.java b/java/src/juejin/lc/leetCode/IsPowerOfThree.java new file mode 100644 index 0000000..61ac15c --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsPowerOfThree.java @@ -0,0 +1,54 @@ +package juejin.lc.leetCode; + +public class IsPowerOfThree { + /** + * 给定一个整数,写一个函数来判断它是否是 3 的幂次方。 + *

+ * 示例 1: + *

+ * 输入: 27 + * 输出: true + * 示例 2: + *

+ * 输入: 0 + * 输出: false + * 示例 3: + *

+ * 输入: 9 + * 输出: true + * 示例 4: + *

+ * 输入: 45 + * 输出: false + * + * @param n 给定整数 + * @return 返回结果 + */ + private boolean solution(int n) { + // 换底公式 + // ps 不能使用 log ,否则会有精度问题 + return (Math.log10(n) / Math.log10(3)) % 1 == 0; + } + + private boolean solution2(int n) { + // 1162261467 是 整数范围内最大的3的幂次方 + return n > 0 && 1162261467 % n == 0; + } + + private boolean solution1(int n) { + if (n < 1) { + return false; + } + while (n % 3 == 0) { + n /= 3; + } + return n == 1; + } + + public static void main(String[] args) { + IsPowerOfThree isPowerOfThree = new IsPowerOfThree(); + int n = 16; + boolean result = isPowerOfThree.solution(n); + System.out.println(result); + } +} diff --git a/java/src/juejin/lc/leetCode/NumArray.java b/java/src/juejin/lc/leetCode/NumArray.java new file mode 100644 index 0000000..a1c689a --- /dev/null +++ b/java/src/juejin/lc/leetCode/NumArray.java @@ -0,0 +1,58 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; + +public class NumArray { + private int[] sum; + + /** + * 给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。 + *

+ * 示例: + *

+ * 给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange() + *

+ * sumRange(0, 2) -> 1 + * sumRange(2, 5) -> -1 + * sumRange(0, 5) -> -3 + * 说明: + *

+ * 你可以假设数组不可变。 + * 会多次调用 sumRange 方法。 + * + * @param nums 数组 + */ + private NumArray(int[] nums) { + sum = new int[nums.length + 1]; + for (int i = 0; i < nums.length; i++) { + sum[i + 1] = sum[i] + nums[i]; + } + System.out.println(Arrays.toString(sum)); + } + + private int sumRange(int i, int j) { + return sum[j + 1] - sum[i]; + } +// private NumArray (int[] nums) { +// this.nums = nums; +// } +// +// private int sumRange(int i, int j) { +// int sum = 0; +// for (int k = i; k <= j; k++) { +// sum += nums[k]; +// } +// return sum; +// } + + public static void main(String[] args) { + int[] nums = {-2, 0, 3, -5, 2, -1}; + NumArray numArray = new NumArray(nums); + int res1 = numArray.sumRange(0, 2); + System.out.println("res1 = " + res1); + int res2 = numArray.sumRange(2, 5); + System.out.println("res2 = " + res2); + int res3 = numArray.sumRange(0, 5); + System.out.println("res3 = " + res3); + } +} From c347331d1fcbfb508cb4edcdc8e74982a926ade1 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Wed, 25 Dec 2019 15:11:47 +0800 Subject: [PATCH 30/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B412=E6=9C=8825=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/juejin/lc/leetCode/ReverseString.java | 41 ++++++++++++++ .../src/juejin/lc/leetCode/ReverseVowels.java | 55 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/ReverseString.java create mode 100644 java/src/juejin/lc/leetCode/ReverseVowels.java diff --git a/java/src/juejin/lc/leetCode/ReverseString.java b/java/src/juejin/lc/leetCode/ReverseString.java new file mode 100644 index 0000000..617ae4c --- /dev/null +++ b/java/src/juejin/lc/leetCode/ReverseString.java @@ -0,0 +1,41 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; + +public class ReverseString { + /** + * 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 + *

+ * 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 + *

+ * 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入:['h','e','l','l','o'] + * 输出:['o','l','l','e','h'] + * 示例 2: + *

+ * 输入:['H','a','n','n','a','h'] + * 输出:['h','a','n','n','a','H'] + * + * @param s 指定字符串 + */ + private void solution(char[] s) { + int mid = s.length / 2; + for (int i = 0; i < mid; i++) { + char temp = s[i]; + s[i] = s[s.length - 1 - i]; + s[s.length - 1 - i] = temp; + } + } + + public static void main(String[] args) { + char[] s = {'h', 'e', 'l', 'l', 'o'}; + ReverseString reverseString = new ReverseString(); + reverseString.solution(s); + System.out.println(Arrays.toString(s)); + } +} diff --git a/java/src/juejin/lc/leetCode/ReverseVowels.java b/java/src/juejin/lc/leetCode/ReverseVowels.java new file mode 100644 index 0000000..1509186 --- /dev/null +++ b/java/src/juejin/lc/leetCode/ReverseVowels.java @@ -0,0 +1,55 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class ReverseVowels { + /** + * 编写一个函数,以字符串作为输入,反转该字符串中的元音字母。 + *

+ * 示例 1: + *

+ * 输入: "hello" + * 输出: "holle" + * 示例 2: + *

+ * 输入: "leetcode" + * 输出: "leotcede" + * 说明: + * 元音字母不包含字母"y"。 + * + * @param s 字符串 + * @return 返回值 + */ + private String solution(String s) { + // 双指针 + String vowel = "aeiouAEIOU"; + char[] chars = s.toCharArray(); + int i = 0; + int j = chars.length - 1; + while (i < j) { + if (vowel.contains(chars[i] + "")) { + if (vowel.contains(chars[j] + "")) { + char temp = chars[i]; + chars[i] = chars[j]; + chars[j] = temp; + ++i; + --j; + } else { + --j; + } + } else { + ++i; + } + } + return String.valueOf(chars); + } + + public static void main(String[] args) { + ReverseVowels reverseVowels = new ReverseVowels(); + String s = "leetcode"; + String result = reverseVowels.solution(s); + System.out.println("result = " + result); + } +} From efd7ddb0b589e7bdaf38d4bcb97956ccc3c5423e Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Mon, 30 Dec 2019 16:13:49 +0800 Subject: [PATCH 31/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0=202019=E5=B9=B412=E6=9C=8830=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/Intersect.java | 64 +++++++++++++++ java/src/juejin/lc/leetCode/Intersection.java | 80 +++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/Intersect.java create mode 100644 java/src/juejin/lc/leetCode/Intersection.java diff --git a/java/src/juejin/lc/leetCode/Intersect.java b/java/src/juejin/lc/leetCode/Intersect.java new file mode 100644 index 0000000..020e704 --- /dev/null +++ b/java/src/juejin/lc/leetCode/Intersect.java @@ -0,0 +1,64 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Intersect { + /** + * 给定两个数组,编写一个函数来计算它们的交集。 + *

+ * 示例 1: + *

+ * 输入: nums1 = [1,2,2,1], nums2 = [2,2] + * 输出: [2,2] + * 示例 2: + *

+ * 输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * 输出: [4,9] + * 说明: + *

+ * 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。 + * 我们可以不考虑输出结果的顺序。 + * 进阶: + *

+ * 如果给定的数组已经排好序呢?你将如何优化你的算法? + * 如果 nums1 的大小比 nums2 小很多,哪种方法更优? + * 如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办? + * + * @param nums1 数组一 + * @param nums2 数组二 + * @return 返回结果 + */ + private int[] solution(int[] nums1, int[] nums2) { + List list1 = new ArrayList<>(); + for (Integer n : nums1) { + list1.add(n); + } + List list2 = new ArrayList<>(); + for (Integer n : nums2) { + list2.add(n); + } + return nums1.length > nums2.length ? setIntersect(list2, list1) : setIntersect(list1, list2); + } + + private int[] setIntersect(List list1, List list2) { + int[] output = new int[list1.size()]; + int idx = 0; + for (Integer s : list1) { + if (list2.contains(s)) { + output[idx++] = s; + list2.remove(s); + } + } + return Arrays.copyOf(output, idx); + } + + public static void main(String[] args) { + Intersect intersect = new Intersect(); + int[] nums1 = {3, 1, 2}; + int[] nums2 = {1, 1}; + int[] arrs = intersect.solution(nums1, nums2); + System.out.println("arrs = " + Arrays.toString(arrs)); + } +} diff --git a/java/src/juejin/lc/leetCode/Intersection.java b/java/src/juejin/lc/leetCode/Intersection.java new file mode 100644 index 0000000..d9a7eda --- /dev/null +++ b/java/src/juejin/lc/leetCode/Intersection.java @@ -0,0 +1,80 @@ +package juejin.lc.leetCode; + + +import java.util.Arrays; +import java.util.HashSet; + +public class Intersection { + /** + * 给定两个数组,编写一个函数来计算它们的交集。 + *

+ * 示例 1: + *

+ * 输入: nums1 = [1,2,2,1], nums2 = [2,2] + * 输出: [2] + * 示例 2: + *

+ * 输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * 输出: [9,4] + * 说明: + *

+ * 输出结果中的每个元素一定是唯一的。 + * 我们可以不考虑输出结果的顺序。 + * retainAll + * + * @param nums1 数组一 + * @param nums2 数组二 + * @return 交集数组 + */ + public int[] solution(int[] nums1, int[] nums2) { + HashSet set1 = new HashSet(); + for (Integer n : nums1) { + set1.add(n); + } + HashSet set2 = new HashSet(); + for (Integer n : nums2) { + set2.add(n); + } + + set1.retainAll(set2); + + int[] output = new int[set1.size()]; + int idx = 0; + for (int s : set1) { + output[idx++] = s; + } + return output; + } + + private int[] solution1(int[] nums1, int[] nums2) { + HashSet set1 = new HashSet<>(); + for (Integer n : nums1) { + set1.add(n); + } + HashSet set2 = new HashSet<>(); + for (Integer n : nums2) { + set2.add(n); + } + // retainAll A.retainAll(B) A去重,去掉包含B的部分 + return nums1.length > nums2.length ? setIntersection(set2, set1) : setIntersection(set1, set2); + } + + private int[] setIntersection(HashSet set2, HashSet set1) { + int[] output = new int[set1.size()]; + int idx = 0; + for (Integer s : set1) { + if (set2.contains(s)) { + output[idx++] = s; + } + } + return Arrays.copyOf(output, idx); + } + + public static void main(String[] args) { + Intersection intersection = new Intersection(); + int[] nums1 = {4, 9, 5}; + int[] nums2 = {9, 4, 9, 8, 4}; + int[] arrs = intersection.solution(nums1, nums2); + System.out.println("arrs = " + Arrays.toString(arrs)); + } +} From a458d40a886914cda69b7b069f268f304d1396af Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Tue, 10 Mar 2020 09:45:18 +0800 Subject: [PATCH 32/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2019=E5=B9=B43=E6=9C=8810=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/CanConstruct.java | 62 +++++++++++++++++++ .../juejin/lc/leetCode/FindTheDifference.java | 52 ++++++++++++++++ .../src/juejin/lc/leetCode/FirstUniqChar.java | 34 ++++++++++ java/src/juejin/lc/leetCode/GetSum.java | 49 +++++++++++++++ java/src/juejin/lc/leetCode/GuessNumber.java | 55 ++++++++++++++++ .../juejin/lc/leetCode/IsPerfectSquare.java | 60 ++++++++++++++++++ .../src/juejin/lc/leetCode/IsSubsequence.java | 50 +++++++++++++++ .../juejin/lc/leetCode/MaxNumberMatrix.java | 31 ++++++++++ 8 files changed, 393 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/CanConstruct.java create mode 100644 java/src/juejin/lc/leetCode/FindTheDifference.java create mode 100644 java/src/juejin/lc/leetCode/FirstUniqChar.java create mode 100644 java/src/juejin/lc/leetCode/GetSum.java create mode 100644 java/src/juejin/lc/leetCode/GuessNumber.java create mode 100644 java/src/juejin/lc/leetCode/IsPerfectSquare.java create mode 100644 java/src/juejin/lc/leetCode/IsSubsequence.java create mode 100644 java/src/juejin/lc/leetCode/MaxNumberMatrix.java diff --git a/java/src/juejin/lc/leetCode/CanConstruct.java b/java/src/juejin/lc/leetCode/CanConstruct.java new file mode 100644 index 0000000..da18a76 --- /dev/null +++ b/java/src/juejin/lc/leetCode/CanConstruct.java @@ -0,0 +1,62 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CanConstruct { + /** + * 给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串, + * 判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成。 + * 如果可以构成,返回 true ;否则返回 false。 + *

+ * (题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。) + *

+ * 注意: + *

+ * 你可以假设两个字符串均只含有小写字母。 + *

+ * canConstruct("a", "b") -> false + * canConstruct("aa", "ab") -> false + * canConstruct("aa", "aab") -> true + * + * @param ransomNote 赎金信 + * @param magazine 杂志 + * @return 返回结果 + */ + private boolean solution(String ransomNote, String magazine) { + if (magazine.length() < ransomNote.length()) { + return false; + } + char[] ransomNoteChars = ransomNote.toCharArray(); + int[] caps = new int[26]; + for (char ransomNoteChar : ransomNoteChars) { + int index = magazine.indexOf(ransomNoteChar, caps[ransomNoteChar - 'a']); + if (index == -1) { + return false; + } + caps[ransomNoteChar - 'a'] = index + 1; + } + return true; + } + + private boolean solution1(String ransomNote, String magazine) { + if (magazine.length() < ransomNote.length()) { + return false; + } + char[] ransomNoteChars = ransomNote.toCharArray(); + char[] magazineChars = magazine.toCharArray(); + List list = new ArrayList<>(); + for (Character magazineChar : magazineChars) { + list.add(magazineChar); + } + for (Character ransomNoteChar : ransomNoteChars) { + if (list.contains(ransomNoteChar)) { + list.remove(ransomNoteChar); + } else { + return false; + } + } + return true; + } +} diff --git a/java/src/juejin/lc/leetCode/FindTheDifference.java b/java/src/juejin/lc/leetCode/FindTheDifference.java new file mode 100644 index 0000000..8c94a11 --- /dev/null +++ b/java/src/juejin/lc/leetCode/FindTheDifference.java @@ -0,0 +1,52 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class FindTheDifference { + /** + * 给定两个字符串 s 和 t,它们只包含小写字母。 + *

+ * 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。 + *

+ * 请找出在 t 中被添加的字母。 + *

+ *   + *

+ * 示例: + *

+ * 输入: + * s = "abcd" + * t = "abcde" + *

+ * 输出: + * e + *

+ * 解释: + * 'e' 是那个被添加的字母。 + * + * @param s 字符串 + * @param t 字符串 + * @return res + */ + private char solution(String s, String t) { + char difference = 0; + for (int i = 0; i < s.length(); i++) { + difference ^= s.charAt(i); + } + for (int i = 0; i < t.length(); i++) { + difference ^= t.charAt(i); + } + return difference; + } + + public static void main(String[] args) { + String s = "abcd"; + String t = "abcde"; + FindTheDifference findTheDifference = new FindTheDifference(); + char res = findTheDifference.solution(s,t); + System.out.println("res = " + res); + } +} diff --git a/java/src/juejin/lc/leetCode/FirstUniqChar.java b/java/src/juejin/lc/leetCode/FirstUniqChar.java new file mode 100644 index 0000000..7a687f4 --- /dev/null +++ b/java/src/juejin/lc/leetCode/FirstUniqChar.java @@ -0,0 +1,34 @@ +package juejin.lc.leetCode; + +public class FirstUniqChar { + /** + * 给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。 + *

+ * 案例: + *

+ * s = "leetcode" + * 返回 0. + *

+ * s = "loveleetcode", + * 返回 2. + * + * @param s s + * @return r + */ + private int solution(String s) { + char[] chars = s.toCharArray(); + for (int i = 0; i < chars.length; i++) { + if (s.indexOf(chars[i]) == s.lastIndexOf(chars[i])) { + return i; + } + } + return -1; + } + + public static void main(String[] args) { + FirstUniqChar firstUniqChar = new FirstUniqChar(); + String s = "cc"; + int res = firstUniqChar.solution(s); + System.out.println("res = " + res); + } +} diff --git a/java/src/juejin/lc/leetCode/GetSum.java b/java/src/juejin/lc/leetCode/GetSum.java new file mode 100644 index 0000000..6b9c951 --- /dev/null +++ b/java/src/juejin/lc/leetCode/GetSum.java @@ -0,0 +1,49 @@ +package juejin.lc.leetCode; + +public class GetSum { + /** + * 不使用运算符 + 和 -,计算两整数a 、b之和。 + *

+ * 示例 1: + *

+ * 输入: a = 1, b = 2 + * 输出: 3 + * 示例 2: + *

+ * 输入: a = -2, b = 3 + * 输出: 1 + * TODO + * @param a 整数 a + * @param b 整数 b + * @return 整数和 + */ + private int solution(int a, int b) { + //进位 + int jw = a & b; + System.out.println("first jw = " + jw); + //相加位 + a = a ^ b; + System.out.println("first a = " + a); + System.out.println(); + while (jw != 0) { + //左移进位作为新的b + b = jw << 1; + System.out.println("b = " + b); + //进位 + jw = a & b; + System.out.println("jw = " + jw); + //相加位 + a = a ^ b; + System.out.println("a = " + a); + } + return a; + } + + public static void main(String[] args) { + GetSum getSum = new GetSum(); + int a = 2; + int b = 3; + int sum = getSum.solution(a, b); + System.out.println("sum = " + sum); + } +} diff --git a/java/src/juejin/lc/leetCode/GuessNumber.java b/java/src/juejin/lc/leetCode/GuessNumber.java new file mode 100644 index 0000000..050fb9a --- /dev/null +++ b/java/src/juejin/lc/leetCode/GuessNumber.java @@ -0,0 +1,55 @@ +package juejin.lc.leetCode; + +public class GuessNumber { + /** + * 我们正在玩一个猜数字游戏。 游戏规则如下: + * 我从 1 到 n 选择一个数字。 你需要猜我选择了哪个数字。 + * 每次你猜错了,我会告诉你这个数字是大了还是小了。 + * 你调用一个预先定义好的接口 guess(int num),它会返回 3 个可能的结果(-1,1 或 0): + *

+ * -1 : 我的数字比较小 + * 1 : 我的数字比较大 + * 0 : 恭喜!你猜对了! + * 示例 : + *

+ * 输入: n = 10, pick = 6 + * 输出: 6 + * + * @param n 数字范围 + * @return 返回值 + */ + private int solution(int n) { + int low = 1; + int high = n; + while (low <= high) { + int mid = low + (high - low) / 2; + int res = guess(mid); + if (res == 0) { + return mid; + } else if (res < 0) { + high = mid - 1; + } else { + low = mid + 1; + } + } + return -1; + } + + private int pick = 6; + + private int guess(int num) { + if (num > pick) { + return -1; + } else if (num < pick) { + return 1; + } + return 0; + } + + public static void main(String[] args) { + GuessNumber guessNumber = new GuessNumber(); + int n = 10; + int res = guessNumber.solution(n); + System.out.println("res = " + res); + } +} diff --git a/java/src/juejin/lc/leetCode/IsPerfectSquare.java b/java/src/juejin/lc/leetCode/IsPerfectSquare.java new file mode 100644 index 0000000..8c030e8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsPerfectSquare.java @@ -0,0 +1,60 @@ +package juejin.lc.leetCode; + +public class IsPerfectSquare { + /** + * 给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。 + *

+ * 说明:不要使用任何内置的库函数,如  sqrt。 + *

+ * 示例 1: + *

+ * 输入:16 + * 输出:True + * 示例 2: + *

+ * 输入:14 + * 输出:False + * + * @param num 正整数 + * @return 是否是完全平方数 + */ + private boolean solution(int num) { + // 牛顿迭代法 天下第一 + if (num == 1) { + return true; + } + long x = num >> 1; + while (x * x > num) { + x = (x + num / x) >> 1; + } + return (x * x == num); + } + + private boolean solution1(int num) { + // 常规思路 + if (num == 1) { + return true; + } + long left = 2; + long right = num / 2; + while (left <= right) { + long mid = left + ((right - left) >> 1); + long guessSquared = mid * mid; + if (guessSquared > num) { + right = mid - 1; + } else if (guessSquared < num) { + left = mid + 1; + } else { + return true; + } + } + return false; + } + + public static void main(String[] args) { + IsPerfectSquare isPerfectSquare = new IsPerfectSquare(); + int num = 2147395600; + boolean result = isPerfectSquare.solution(num); + System.out.println("result = " + result); + } +} diff --git a/java/src/juejin/lc/leetCode/IsSubsequence.java b/java/src/juejin/lc/leetCode/IsSubsequence.java new file mode 100644 index 0000000..cea2ffa --- /dev/null +++ b/java/src/juejin/lc/leetCode/IsSubsequence.java @@ -0,0 +1,50 @@ +package juejin.lc.leetCode; + +public class IsSubsequence { + /** + * 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 + *

+ * 你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000), + * 而 s 是个短字符串(长度 <=100)。 + *

+ * 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。 + * (例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 + *

+ * 示例 1: + * s = "abc", t = "ahbgdc" + *

+ * 返回 true. + *

+ * 示例 2: + * s = "axc", t = "ahbgdc" + *

+ * 返回 false. + *

+ * 后续挑战 : + *

+ * 如果有大量输入的 S,称作S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。 + * 在这种情况下,你会怎样改变代码? + * + * @param s 字符串 + * @param t 字符串 + * @return 返回结果 + */ + private boolean solution(String s, String t) { + int index = -1; + for (int i = 0; i < s.length(); i++) { + index = t.indexOf(s.charAt(i), index + 1); + if (index == -1) { + return false; + } + } + return true; + } + + public static void main(String[] args) { + String s = "abc"; + String t = "ahbgdc"; + IsSubsequence isSubsequence = new IsSubsequence(); + boolean res = isSubsequence.solution(s, t); + System.out.println("res = " + res); + } +} diff --git a/java/src/juejin/lc/leetCode/MaxNumberMatrix.java b/java/src/juejin/lc/leetCode/MaxNumberMatrix.java new file mode 100644 index 0000000..4eec90e --- /dev/null +++ b/java/src/juejin/lc/leetCode/MaxNumberMatrix.java @@ -0,0 +1,31 @@ +package juejin.lc.leetCode; + +public class MaxNumberMatrix { + /** + * 给定一个非空二维矩阵 matrix 和一个整数 k,找到这个矩阵内部不大于 k 的最大矩形和。 + * TODO + * @param matrix 二维矩阵 + * @param k 整数 + * @return 最大矩形和 + */ + private int solution(int[][] matrix, int k) { + int rowLen = matrix.length; + int colLen = matrix[0].length; + int max = matrix[0][0]; + for (int i = 0; i < rowLen; i++) { + for (int j = 0; j < colLen; j++) { + System.out.println("matrix[" + i + "][" + j + "] = " + matrix[i][j]); + } + System.out.println(); + } + return max; + } + + public static void main(String[] args) { + int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + int k = 25; + MaxNumberMatrix maxNumberMatrix = new MaxNumberMatrix(); + int result = maxNumberMatrix.solution(matrix, k); + System.out.println("result = " + result); + } +} From 80689e340162e179ca5fd509c2c66470b0e29362 Mon Sep 17 00:00:00 2001 From: liuchao Date: Fri, 7 Aug 2020 01:07:28 +0800 Subject: [PATCH 33/43] =?UTF-8?q?fix=20=E5=BF=AB=E6=8E=92=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/sorts/BaseSort.java | 34 +++++++++++++++----------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/java/src/juejin/lc/sorts/BaseSort.java b/java/src/juejin/lc/sorts/BaseSort.java index 4ccc099..dc1549e 100644 --- a/java/src/juejin/lc/sorts/BaseSort.java +++ b/java/src/juejin/lc/sorts/BaseSort.java @@ -87,12 +87,14 @@ private int[] selectionSort(int[] arrays) { * @param tail 数组尾 */ private void quickSort(int[] arrays, int head, int tail) { - if (head >= tail) return; + if (head >= tail) { + return; + } + // 获取分区点 int pivot = partition(arrays, head, tail); - quickSort(arrays, head, tail - 1); + quickSort(arrays, head, pivot - 1); quickSort(arrays, pivot + 1, tail); } - /** * 分区函数 * @@ -104,18 +106,22 @@ private void quickSort(int[] arrays, int head, int tail) { private int partition(int[] arrays, int head, int tail) { int pivot = arrays[tail]; int i = head; - for (int j = head; j < tail; j++) { - if (pivot > arrays[j]) { - int tmp = arrays[i]; - arrays[i] = arrays[j]; - arrays[j] = tmp; - ++i; + for (int j = head; j < tail; ++j) { + if (arrays[j] < pivot) { + if(i == j) { + ++i; + } else { + int tmp = arrays[i]; + arrays[i++] = arrays[j]; + arrays[j] = tmp; + } } } int tmp = arrays[i]; arrays[i] = arrays[tail]; arrays[tail] = tmp; - return pivot; +// System.out.println("i=" + i); + return i; } /** @@ -203,9 +209,9 @@ public static void main(String[] args) { baseSort.quickSort(quickArray, 0, quickArray.length - 1); System.out.print("快速排序:"); baseSort.printAll(quickArray); - int[] mergeArray = {2, 4, 1, 3, 6, 5}; - baseSort.mergeSort(mergeArray, 0, mergeArray.length - 1); - System.out.print("归并排序:"); - baseSort.printAll(mergeArray); +// int[] mergeArray = {2, 4, 1, 3, 6, 5}; +// baseSort.mergeSort(mergeArray, 0, mergeArray.length - 1); +// System.out.print("归并排序:"); +// baseSort.printAll(mergeArray); } } From fd7a59580056637c4e66f15e84964681747536ea Mon Sep 17 00:00:00 2001 From: liuchao Date: Sun, 9 Aug 2020 16:31:02 +0800 Subject: [PATCH 34/43] =?UTF-8?q?=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=2020?= =?UTF-8?q?20=E5=B9=B48=E6=9C=889=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juejin/lc/leetCode/LongestPalindrome.java | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/LongestPalindrome.java diff --git a/java/src/juejin/lc/leetCode/LongestPalindrome.java b/java/src/juejin/lc/leetCode/LongestPalindrome.java new file mode 100644 index 0000000..9ac5785 --- /dev/null +++ b/java/src/juejin/lc/leetCode/LongestPalindrome.java @@ -0,0 +1,91 @@ +package juejin.lc.leetCode; + +/** + * 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 + * + * 示例 1: + * + * 输入: "babad" + * 输出: "bab" + * 注意: "aba" 也是一个有效答案。 + * 示例 2: + * + * 输入: "cbbd" + * 输出: "bb" + * + */ +public class LongestPalindrome { + /** + * 动态规划 + * @param s + * @return + */ + public String solution1(String s) { + // 边界条件 + int n = s.length(); + if (n < 2) { + return s; + } + char[] chars = s.toCharArray(); + boolean[][] dp = new boolean[n][n]; + for (int i = 0; i < n; i++) { + dp[i][i] = true; + } + int begin = 0; + int offset = 1; + for (int j = 1; j < n; j++) { + for (int i = 0; i < j; i++) { + if (chars[i] != chars[j]) { + dp[i][j] = false; + } else { + if (j - i < 3) { + dp[i][j] = true; + } else { + dp[i][j] = dp[i + 1][j - 1]; + } + } + if (dp[i][j] && j - i + 1> offset) { + offset = j - i + 1; + begin = i; + } + } + } + return s.substring(begin, begin + offset); + } + /** + * 暴力破解法 + * @param s 字符串 + * @return 最长回文串 + */ + public String solution(String s) { + // 先判断边界条件 + int n = s.length(); + if (n < 2) { + return s; + } + char[] chars = s.toCharArray(); + int begin = 0; + // 最差情况,给定的字符串没有大于1的回文串情况,取一位 + int offset = 1; + for (int i = 0; i < n - 1; i++) { + for (int j = i + 1; j < n; j++) { + if (j - i + 1 > offset && isPalindrome(chars, i,j)) { + begin = i; + offset = j - i + 1; + } + } + } + return s.substring(begin, begin + offset); + } + public boolean isPalindrome(char[] chars, int begin, int end) { + // 边界条件 不考虑 begin >= end 情况 + while (begin < end) { + if (chars[begin] != chars[end]) { + return false; + } + ++begin; + --end; + } + return true; + } +} From 531717fa47784e5a4defcca4072064dce7be6704 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Thu, 13 Aug 2020 18:19:51 +0800 Subject: [PATCH 35/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juejin/lc/leetCode/ReadBinaryWatch.java | 59 +++++++++++++++++++ .../juejin/lc/leetCode/RemoveNthFromEnd.java | 51 ++++++++++++++++ .../juejin/lc/leetCode/SumOfLeftLeaves.java | 58 ++++++++++++++++++ java/src/juejin/lc/leetCode/ToHex.java | 35 +++++++++++ java/src/juejin/lc/sorts/BaseSort.java | 8 +-- 5 files changed, 207 insertions(+), 4 deletions(-) create mode 100644 java/src/juejin/lc/leetCode/ReadBinaryWatch.java create mode 100644 java/src/juejin/lc/leetCode/RemoveNthFromEnd.java create mode 100644 java/src/juejin/lc/leetCode/SumOfLeftLeaves.java create mode 100644 java/src/juejin/lc/leetCode/ToHex.java diff --git a/java/src/juejin/lc/leetCode/ReadBinaryWatch.java b/java/src/juejin/lc/leetCode/ReadBinaryWatch.java new file mode 100644 index 0000000..36dddbe --- /dev/null +++ b/java/src/juejin/lc/leetCode/ReadBinaryWatch.java @@ -0,0 +1,59 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * 二进制手表顶部有 4 个 LED 代表小时(0-11),底部的 6 个 LED 代表分钟(0-59)。 + * 0 0 0 0 + * 32 16 8 4 2 1 + *

+ * 每个 LED 代表一个 0 或 1,最低位在右侧。 + *

+ * 给定一个非负整数 n 代表当前 LED 亮着的数量,返回所有可能的时间。 + *

+ * 案例: + *

+ * 输入: n = 1 + * 返回: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"] + *

+ * 注意事项: + *

+ * 输出的顺序没有要求。 + * 小时不会以零开头,比如 “01:00” 是不允许的,应为 “1:00”。 + * 分钟必须由两位数组成,可能会以零开头,比如 “10:2” 是无效的,应为 “10:02”。 + */ +public class ReadBinaryWatch { + public List solution(int num) { + List ans = new ArrayList<>(); + String[][] hstrs = {{"0"}, {"1", "2", "4", "8"}, {"3", "5", "6", "9", "10"}, {"7", "11"}}; + String[][] mstrs = {{"00"}, {"01", "02", "04", "08", "16", "32"}, + {"03", "05", "06", "09", "10", "12", "17", "18", "20", "24", "33", "34", "36", "40", "48"}, + {"07", "11", "13", "14", "19", "21", "22", "25", "26", "28", "35", "37", "38", "41", "42", "44", "49", "50", "52", "56"}, + {"15", "23", "27", "29", "30", "39", "43", "45", "46", "51", "53", "54", "57", "58"}, + {"31", "47", "55", "59"}}; + int min = 3; + for (int i = 0; i <= Math.min(min, num); i++) { + if (num - i > 5) { + continue; + } + String[] hstr = hstrs[i]; + String[] mstr = mstrs[num - i]; + for (String value : hstr) { + for (String s : mstr) { + ans.add(value + ":" + s); + } + } + } + return ans; + + } + + public static void main(String[] args) { + ReadBinaryWatch readBinaryWatch = new ReadBinaryWatch(); + int n = 1; + System.out.println(readBinaryWatch.solution(n).toString()); + } +} diff --git a/java/src/juejin/lc/leetCode/RemoveNthFromEnd.java b/java/src/juejin/lc/leetCode/RemoveNthFromEnd.java new file mode 100644 index 0000000..0f84637 --- /dev/null +++ b/java/src/juejin/lc/leetCode/RemoveNthFromEnd.java @@ -0,0 +1,51 @@ +package juejin.lc.leetCode; + +public class RemoveNthFromEnd { + /** + * 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 + *

+ * 示例: + *

+ * 给定一个链表: 1->2->3->4->5, 和 n = 2. + *

+ * 当删除了倒数第二个节点后,链表变为 1->2->3->5. + * + * @param head + * @param n + * @return + */ + public ListNode solution(ListNode head, int n) { + // 快慢指针法 + ListNode fast = head; + int i = 1; + while (i < n && null != fast) { + fast = fast.next; + ++i; + } + if (null == fast) { + return head; + } + ListNode slow = head; + ListNode prevNode = null; + while (null != fast.next) { + fast = fast.next; + prevNode = slow; + slow = slow.next; + } + if (null == prevNode) { + head = head.next; + } else { + prevNode.next = prevNode.next.next; + } + return head; + } + + public class ListNode { + int val; + ListNode next; + + ListNode(int x) { + val = x; + } + } +} diff --git a/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java b/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java new file mode 100644 index 0000000..d9374b8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java @@ -0,0 +1,58 @@ +package juejin.lc.leetCode; + +public class SumOfLeftLeaves { + private int sum = 0; + /** + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 + * @param root 二叉树 + * @return 返回和 + */ + public int solution(TreeNode root) { + recursion(root,"root"); + return sum; + } + private void recursion(TreeNode treeNode, String type) { + if (null == treeNode) return; + System.out.println(treeNode.val + " " + type); + if ("left".equals(type) && null == treeNode.left && null == treeNode.right){ + sum += treeNode.val; + } + System.out.println("sum ====>" + sum); + recursion(treeNode.left,"left"); + recursion(treeNode.right,"right"); + } + + private TreeNode createNode() { + TreeNode treeNode = new TreeNode(1); + TreeNode treeNode1 = new TreeNode(9); + TreeNode treeNode2 = new TreeNode(20); + treeNode.left = treeNode1; + treeNode.right = treeNode2; + TreeNode treeNode3 = new TreeNode(15); + TreeNode treeNode4 = new TreeNode(7); + treeNode2.left = treeNode3; + treeNode2.right = treeNode4; + return treeNode; + } + public static void main(String[] args) { + SumOfLeftLeaves sumOfLeftLeaves = new SumOfLeftLeaves(); + TreeNode treeNode = sumOfLeftLeaves.createNode(); + int res = sumOfLeftLeaves.solution(treeNode); + System.out.println("res = " + res); + } + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } +} diff --git a/java/src/juejin/lc/leetCode/ToHex.java b/java/src/juejin/lc/leetCode/ToHex.java new file mode 100644 index 0000000..1b5735b --- /dev/null +++ b/java/src/juejin/lc/leetCode/ToHex.java @@ -0,0 +1,35 @@ +package juejin.lc.leetCode; + +import java.util.HashMap; + +public class ToHex { + /** + * 给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。 + * 注意: + * 十六进制中所有字母(a-f)都必须是小写。 + * 十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示; + * 对于其他情况,十六进制字符串中的第一个字符将不会是0字符。  + * 给定的数确保在32位有符号整数范围内。 + * 不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。 + * 示例 1: + * + * 输入: + * 26 + * + * 输出: + * "1a" + * 示例 2: + * + * 输入: + * -1 + * + * 输出: + * "ffffffff" + * @param num + * @return + */ + public String solution(int num) { + HashMap map = new HashMap(); + return ""; + } +} diff --git a/java/src/juejin/lc/sorts/BaseSort.java b/java/src/juejin/lc/sorts/BaseSort.java index dc1549e..8687628 100644 --- a/java/src/juejin/lc/sorts/BaseSort.java +++ b/java/src/juejin/lc/sorts/BaseSort.java @@ -209,9 +209,9 @@ public static void main(String[] args) { baseSort.quickSort(quickArray, 0, quickArray.length - 1); System.out.print("快速排序:"); baseSort.printAll(quickArray); -// int[] mergeArray = {2, 4, 1, 3, 6, 5}; -// baseSort.mergeSort(mergeArray, 0, mergeArray.length - 1); -// System.out.print("归并排序:"); -// baseSort.printAll(mergeArray); + int[] mergeArray = {2, 4, 1, 3, 6, 5}; + baseSort.mergeSort(mergeArray, 0, mergeArray.length - 1); + System.out.print("归并排序:"); + baseSort.printAll(mergeArray); } } From 21240d840f272a74ca2f58e2544e8920ad89e6eb Mon Sep 17 00:00:00 2001 From: liuchao Date: Wed, 19 Aug 2020 23:12:51 +0800 Subject: [PATCH 36/43] =?UTF-8?q?=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=2020?= =?UTF-8?q?20=E5=B9=B48=E6=9C=8819=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/LevelOrder.java | 67 +++++++++++++++++++ .../juejin/lc/leetCode/SumOfLeftLeaves.java | 57 ++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/LevelOrder.java create mode 100644 java/src/juejin/lc/leetCode/SumOfLeftLeaves.java diff --git a/java/src/juejin/lc/leetCode/LevelOrder.java b/java/src/juejin/lc/leetCode/LevelOrder.java new file mode 100644 index 0000000..20d5f4f --- /dev/null +++ b/java/src/juejin/lc/leetCode/LevelOrder.java @@ -0,0 +1,67 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +public class LevelOrder { + /** + * 给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。 + * + *   + * + * 示例: + * 二叉树:[3,9,20,null,null,15,7], + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * 返回其层次遍历结果: + * + * [ + * [3], + * [9,20], + * [15,7] + * ] + * + * @param root + * @return + */ + public List> solution(TreeNode root) { + if (null == root) { + return new ArrayList<>(); + } + List> list = new ArrayList<>(); + LinkedList linkedList = new LinkedList<>(); + linkedList.offer(root); + while (!linkedList.isEmpty()) { + int size = linkedList.size(); + List child = new ArrayList<>(); + for (int i = 0; i < size; i++) { + TreeNode node = linkedList.poll(); + if (null != node) { + child.add(node.val); + if (null != node.left) { + linkedList.offer(node.left); + } + if (null != node.right) { + linkedList.offer(node.right); + } + } + } + list.add(child); + } + return list; +} + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } +} diff --git a/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java b/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java new file mode 100644 index 0000000..c2169d8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java @@ -0,0 +1,57 @@ +package juejin.lc.leetCode; + +public class SumOfLeftLeaves { + /** + * 计算给定二叉树的所有左叶子之和。 + * + * 示例: + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 + * + * @param root + * @return + */ + public int solution(TreeNode root) { + // 边界条件 + if (null == root) { + return 0; + } + return recursion(root, false); + } + + /** + * + * @param root 二叉树 + * @param flag 是否是左节点 + * @return + */ + private int recursion(TreeNode root, boolean flag) { + // 边界条件 + if(null == root) { + return 0; + } + if (flag && null == root.left && null == root.right) { + return root.val; + } + int leftSum = recursion(root.left, true); + int rightSum = recursion(root.right, false); + return leftSum + rightSum; + } + + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } +} From c530061ffec23ca57371e56fe9430221cd86ad4f Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Thu, 20 Aug 2020 14:46:09 +0800 Subject: [PATCH 37/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2020=E5=B9=B48=E6=9C=8820=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lc/leetCode/LongestPalindromeLength.java | 86 +++++++++++++++++++ java/src/juejin/lc/leetCode/ToHex.java | 27 +++++- 2 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 java/src/juejin/lc/leetCode/LongestPalindromeLength.java diff --git a/java/src/juejin/lc/leetCode/LongestPalindromeLength.java b/java/src/juejin/lc/leetCode/LongestPalindromeLength.java new file mode 100644 index 0000000..aaa0bb1 --- /dev/null +++ b/java/src/juejin/lc/leetCode/LongestPalindromeLength.java @@ -0,0 +1,86 @@ +package juejin.lc.leetCode; + +import java.util.HashMap; +import java.util.Map; + +public class LongestPalindromeLength { + /** + * 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。 + * 在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。 + * 注意: + * 假设字符串的长度不会超过 1010。 + * 示例 1: + * 输入: + * "abccccdd" + * 输出: + * 7 + * 解释: + * 我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。 + * + * @param s + * @return + */ + public int solution(String s) { + // 边界条件 + int n = s.length(); + if (n < 2) { + return n; + } + char[] chars = new char[128]; + for (char c : s.toCharArray()) { + ++chars[c]; + } + int ans = 0; + for (int v: chars) { + // 忽略奇数 + ans += v / 2 * 2; + // 填充奇数 + if ((v & 1) == 1 && (ans & 1) == 0) { + ++ans; + } + } + return ans; + } + + public int solution1(String s) { + // 边界条件 + int n = s.length(); + if (n < 2) { + return n; + } + Map map = new HashMap<>(); + char[] chars = s.toCharArray(); + for (int i = 0; i < n; i++) { + if (map.containsKey(chars[i])) { + map.put(chars[i], map.get(chars[i]) + 1); + } else { + map.put(chars[i], 1); + } + } + + // map场景 + // 大于2的均可以2的倍数的长度的字符串作为回文串 + // 然后找一个 奇数的其中一位作为回文串中间值 + int sum = 0; + int center = 0; + for (Map.Entry entry : map.entrySet()) { + int v = entry.getValue(); + if ((v & 1) == 0) { + sum += v; + } else { + // 奇数 + sum += (v - 1); + if (center == 0) { + center = 1; + } + } + } + return sum + center; + } + + public static void main(String[] args) { + String s = "abccccdd"; + int sum = new LongestPalindromeLength().solution(s); + System.out.println("sum = " + sum); + } +} diff --git a/java/src/juejin/lc/leetCode/ToHex.java b/java/src/juejin/lc/leetCode/ToHex.java index 1b5735b..c27875c 100644 --- a/java/src/juejin/lc/leetCode/ToHex.java +++ b/java/src/juejin/lc/leetCode/ToHex.java @@ -29,7 +29,30 @@ public class ToHex { * @return */ public String solution(int num) { - HashMap map = new HashMap(); - return ""; + // 思路,采用位运算 + StringBuilder stringBuilder = new StringBuilder(); + char[] dic = "0123456789abcdef".toCharArray(); + while (num != 0) { + // 与运算 + // 复习一下常用运算符 + // | 按位或 只有有一则为一 + // & 按位与 均为一则为一 + // ^ 按位异或 相同为零不同为一 + int res = num & 15; + stringBuilder.append(dic[res]); + System.out.println("res = " + res); + // 右移四位 + num = num >>> 4; + } + if (stringBuilder.length() == 0) { + stringBuilder.append("0"); + } + return stringBuilder.reverse().toString(); + } + + public static void main(String[] args) { + int num = -287; + String res = new ToHex().solution(num); + System.out.println("res = " + res); } } From 17a2e56b4d0bdcffd256fd27a56c85f042b61240 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Mon, 24 Aug 2020 18:16:10 +0800 Subject: [PATCH 38/43] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=BB=83=E4=B9=A0--2020=E5=B9=B48=E6=9C=8824=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/AddStrings.java | 34 +++++++ java/src/juejin/lc/leetCode/FizzBuzz.java | 98 +++++++++++++++++++++ java/src/juejin/lc/leetCode/ThirdMax.java | 64 ++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/AddStrings.java create mode 100644 java/src/juejin/lc/leetCode/FizzBuzz.java create mode 100644 java/src/juejin/lc/leetCode/ThirdMax.java diff --git a/java/src/juejin/lc/leetCode/AddStrings.java b/java/src/juejin/lc/leetCode/AddStrings.java new file mode 100644 index 0000000..bf41aaf --- /dev/null +++ b/java/src/juejin/lc/leetCode/AddStrings.java @@ -0,0 +1,34 @@ +package juejin.lc.leetCode; + +public class AddStrings { + /** + * 大数相加 + * 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。 + * 提示: + * num1 和num2 的长度都小于 5100 + * num1 和num2 都只包含数字 0-9 + * num1 和num2 都不包含任何前导零 + * 你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式 + * + * @param num1 + * @param num2 + * @return + */ + public String addStrings(String num1, String num2) { + // 边界条件 默认num1和num2均不为null + int n1 = num1.length() - 1; + int n2 = num2.length() - 1; + int index = 0; + StringBuffer ans = new StringBuffer(); + while (n1 >= 0 || n2 >= 0 || index != 0) { + int x = n1 >= 0 ? num1.charAt(n1) - '0' : 0; + int y = n2 >= 0 ? num2.charAt(n2) - '0' : 0; + int result = x + y + index; + ans.append(result % 10); + index = result / 10; + --n1; + --n2; + } + return ans.reverse().toString(); + } +} diff --git a/java/src/juejin/lc/leetCode/FizzBuzz.java b/java/src/juejin/lc/leetCode/FizzBuzz.java new file mode 100644 index 0000000..2c1d0c6 --- /dev/null +++ b/java/src/juejin/lc/leetCode/FizzBuzz.java @@ -0,0 +1,98 @@ +package juejin.lc.leetCode; + +import java.util.ArrayList; +import java.util.List; + +public class FizzBuzz { + /** + * 写一个程序,输出从 1 到 n 数字的字符串表示。 + * + * 1. 如果 n 是3的倍数,输出“Fizz”; + * + * 2. 如果 n 是5的倍数,输出“Buzz”; + * + * 3.如果 n 同时是3和5的倍数,输出 “FizzBuzz”。 + * + * 示例: + * + * n = 15, + * + * 返回: + * [ + * "1", + * "2", + * "Fizz", + * "4", + * "Buzz", + * "Fizz", + * "7", + * "8", + * "Fizz", + * "Buzz", + * "11", + * "Fizz", + * "13", + * "14", + * "FizzBuzz" + * ] + * @param n + * @return + */ + public List solution(int n) { + if (n <= 0) { + return new ArrayList<>(); + } + List list = new ArrayList<>(); + for (int i = 1; i <= n; i++) { + int index = 0; + if (i % 3 == 0) { + index += 1; + } + if (i % 5 == 0) { + index += 2; + } + switch (index) { + case 0: + list.add(String.valueOf(i)); + break; + case 1: + list.add("Fizz"); + break; + case 2: + list.add("Buzz"); + break; + default: + list.add("FizzBuzz"); + break; + } + + } + return list; + } + public List solution1(int n) { + if (n <= 0) { + return new ArrayList<>(); + } + List list = new ArrayList<>(); + for (int i = 1; i <= n; i++) { + String str = ""; + if (i % 3 == 0) { + str += "Fizz"; + } + if (i % 5 == 0) { + str += "Buzz"; + } + if ("".equals(str)) { + str += i; + } + list.add(str); + } + return list; + } + + public static void main(String[] args) { + int n = 15; + List list = new FizzBuzz().solution(n); + System.out.println(list); + } +} diff --git a/java/src/juejin/lc/leetCode/ThirdMax.java b/java/src/juejin/lc/leetCode/ThirdMax.java new file mode 100644 index 0000000..1cd531d --- /dev/null +++ b/java/src/juejin/lc/leetCode/ThirdMax.java @@ -0,0 +1,64 @@ +package juejin.lc.leetCode; + +import java.util.TreeSet; + +public class ThirdMax { + /** + * 给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。 + *

+ * 示例 1: + *

+ * 输入: [3, 2, 1] + *

+ * 输出: 1 + *

+ * 解释: 第三大的数是 1. + * 示例 2: + *

+ * 输入: [1, 2] + *

+ * 输出: 2 + *

+ * 解释: 第三大的数不存在, 所以返回最大的数 2 . + * 示例 3: + *

+ * 输入: [2, 2, 3, 1] + *

+ * 输出: 1 + *

+ * 解释: 注意,要求返回第三大的数,是指第三大且唯一出现的数。 + * 存在两个值为2的数,它们都排第二。 + * + * @param nums + * @return + */ + public int solution(int[] nums) { + // 边界条件 + if (null == nums || nums.length == 0) { + throw new RuntimeException("error"); + } + // 需要去重,第一时间要考虑 set + // 只存放3个元素的 红黑树 + TreeSet treeSet = new TreeSet<>(); + for (int i = 0; i < nums.length; i++) { + treeSet.add(nums[i]); + if (treeSet.size() > 3) { + treeSet.remove(treeSet.first()); + } + } + System.out.println(treeSet); + return treeSet.size() > 2 ? treeSet.first() : treeSet.last(); + } + + public static void main(String[] args) { + int[] nums1 = {3, 2, 1}; + int res1 = new ThirdMax().solution(nums1); + System.out.println("res1 = " + res1); + int[] nums2 = {1, 2}; + int res2 = new ThirdMax().solution(nums2); + System.out.println("res2 = " + res2); + int[] nums3 = {2, 2, 3, 1}; + int res3 = new ThirdMax().solution(nums3); + System.out.println("res3 = " + res3); + } +} From 3ab426cb8f718d5ffc8c1644ff5ff88961f3a039 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Mon, 24 Aug 2020 18:29:54 +0800 Subject: [PATCH 39/43] update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2f62353..73cb335 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Progress Every Day +## LeetCode => [地址](https://github.com/chaoaiqi/study/tree/master/java/src/juejin/lc/leetCode) ## 传送门 ### [01背包](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/BackPack01.java) ### [最大子序列和](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java) From dbb03be5615fdd6ba267eacd510434406d62d736 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Mon, 31 Aug 2020 15:56:50 +0800 Subject: [PATCH 40/43] =?UTF-8?q?=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0=2020?= =?UTF-8?q?20=E5=B9=B48=E6=9C=8831=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/ArrangeCoins.java | 54 +++++++++++++++ java/src/juejin/lc/leetCode/Compress.java | 67 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 java/src/juejin/lc/leetCode/ArrangeCoins.java create mode 100644 java/src/juejin/lc/leetCode/Compress.java diff --git a/java/src/juejin/lc/leetCode/ArrangeCoins.java b/java/src/juejin/lc/leetCode/ArrangeCoins.java new file mode 100644 index 0000000..c0b2639 --- /dev/null +++ b/java/src/juejin/lc/leetCode/ArrangeCoins.java @@ -0,0 +1,54 @@ +package juejin.lc.leetCode; + +public class ArrangeCoins { + /** + * 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。 + * 给定一个数字 n,找出可形成完整阶梯行的总行数。 + * n 是一个非负整数,并且在32位有符号整型的范围内。 + * + * 示例 1: + * n = 5 + * 硬币可排列成以下几行: + * ¤ + * ¤ ¤ + * ¤ ¤ + * 因为第三行不完整,所以返回2. + * + * 示例 2: + * n = 8 + * 硬币可排列成以下几行: + * ¤ + * ¤ ¤ + * ¤ ¤ ¤ + * ¤ ¤ + * 因为第四行不完整,所以返回3. + * @param n + * @return + */ + public int solution(int n) { + // 边界条件 + if(n < 0) { + return 0; + } + if (n == 1) { + return 1; + } + int index = 0; + int num = n; + for (int i = 1; i < n; i++) { + if (num - i >= 0) { + num -= i; + ++index; + } else { + break; + } + } + return index; + } + + public static void main(String[] args) { + int n = 5; + int res = new ArrangeCoins().solution(n); + System.out.println("res = " + res); + } +} diff --git a/java/src/juejin/lc/leetCode/Compress.java b/java/src/juejin/lc/leetCode/Compress.java new file mode 100644 index 0000000..b34d17a --- /dev/null +++ b/java/src/juejin/lc/leetCode/Compress.java @@ -0,0 +1,67 @@ +package juejin.lc.leetCode; + +public class Compress { + /** + * 给定一组字符,使用原地算法将其压缩。 + * 压缩后的长度必须始终小于或等于原数组长度。 + * 数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。 + * 在完成原地修改输入数组后,返回数组的新长度。 + *

+ * 示例 1: + * 输入: + * ["a","a","b","b","c","c","c"] + * 输出: + * 返回 6 ,输入数组的前 6 个字符应该是:["a","2","b","2","c","3"] + * 说明: + * "aa" 被 "a2" 替代。"bb" 被 "b2" 替代。"ccc" 被 "c3" 替代。 + *

+ * 示例 2: + * 输入: + * ["a"] + * 输出: + * 返回 1 ,输入数组的前 1 个字符应该是:["a"] + * 解释: + * 没有任何字符串被替代。 + *

+ * 示例 3: + * 输入: + * ["a","b","b","b","b","b","b","b","b","b","b","b","b"] + * 输出: + * 返回 4 ,输入数组的前4个字符应该是:["a","b","1","2"]。 + * 解释: + * 由于字符 "a" 不重复,所以不会被压缩。"bbbbbbbbbbbb" 被 “b12” 替代。 + * 注意每个数字在数组中都有它自己的位置。 + *

+ * 提示: + * 所有字符都有一个ASCII值在[35, 126]区间内。 + * 1 <= len(chars) <= 1000。 + * + * @param chars + * @return + */ + public int solution(char[] chars) { + // 边界条件 双指针 + // TODO + int anchor = 0, write = 0; + for (int read = 0; read < chars.length; read++) { + if (read + 1 == chars.length || chars[read + 1] != chars[read]) { + chars[write++] = chars[anchor]; + if (read > anchor) { + for (char c : + ("" + (read - anchor + 1)).toCharArray()) { + chars[write++] = c; + } + } + anchor = read + 1; + } + } + + return write; + } + + public static void main(String[] args) { + char[] chars = "aabbccc".toCharArray(); + int ans = new Compress().solution(chars); + System.out.println("ans = " + ans); + } +} From e6fb6542b858e75a526b80fa5cc472078733c293 Mon Sep 17 00:00:00 2001 From: liuchao Date: Sun, 6 Sep 2020 22:33:22 +0800 Subject: [PATCH 41/43] =?UTF-8?q?=E7=AE=97=E6=B3=95=E7=BB=83=E4=B9=A0-2020?= =?UTF-8?q?=E5=B9=B49=E6=9C=886=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/src/juejin/lc/leetCode/Merge.java | 48 ++++++++++++++++++++++++++ java/src/juejin/lc/leetCode/ToHex.java | 2 -- 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 java/src/juejin/lc/leetCode/Merge.java diff --git a/java/src/juejin/lc/leetCode/Merge.java b/java/src/juejin/lc/leetCode/Merge.java new file mode 100644 index 0000000..dabbebc --- /dev/null +++ b/java/src/juejin/lc/leetCode/Merge.java @@ -0,0 +1,48 @@ +package juejin.lc.leetCode; + +import java.util.Arrays; +import java.util.Comparator; + +public class Merge { + /** + * 给出一个区间的集合,请合并所有重叠的区间。 + * + * 示例 1: + * 输入: intervals = [[1,3],[2,6],[8,10],[15,18]] + * 输出: [[1,6],[8,10],[15,18]] + * 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. + * + * 示例 2: + * 输入: intervals = [[1,4],[4,5]] + * 输出: [[1,5]] + * 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。 + * @param intervals + * @return + */ + public static int[][] solution(int[][] intervals) { + // 先按照区间起始位置排序 +// Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]); + Arrays.sort(intervals, Comparator.comparingInt(v -> v[0])); + // 遍历区间 + int[][] res = new int[intervals.length][2]; + int idx = -1; + for (int[] interval: intervals) { + // 如果结果数组是空的,或者当前区间的起始位置> 结果数组的最后区间的终止位置 + // 则不合并、 + if(idx == -1 || interval[0] > res[idx][1]) { + res[++idx] = interval; + } else { + // 反之将当前区间合并至结果数组的最后区间 + res[idx][1] = Math.max(res[idx][1], interval[1]); + } + } + // 取res中有值的数组集合 + return Arrays.copyOf(res, idx + 1); + } + + public static void main(String[] args) { + int[][] nums = {{1,3},{2,6},{8,10},{15,18}}; + int[][] res = solution(nums); + System.out.println(Arrays.deepToString(res)); + } +} diff --git a/java/src/juejin/lc/leetCode/ToHex.java b/java/src/juejin/lc/leetCode/ToHex.java index c27875c..0e48d7f 100644 --- a/java/src/juejin/lc/leetCode/ToHex.java +++ b/java/src/juejin/lc/leetCode/ToHex.java @@ -1,7 +1,5 @@ package juejin.lc.leetCode; -import java.util.HashMap; - public class ToHex { /** * 给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。 From 45e8d99fc099f76c8a1dfad2e311df42033508f1 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Mon, 7 Sep 2020 18:16:15 +0800 Subject: [PATCH 42/43] hot100 go go go --- java/src/juejin/lc/hot100/AddTwoNumbers.java | 51 ++++++++++++ .../lc/hot100/LengthOfLongestSubstring.java | 45 ++++++++++ .../juejin/lc/hot100/LongestPalindrome.java | 83 +++++++++++++++++++ java/src/juejin/lc/hot100/MaxSubArray.java | 47 +++++++++++ java/src/juejin/lc/hot100/TwoSum.java | 33 ++++++++ .../lc/leetCode/LengthOfLongestSubstring.java | 3 +- 6 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 java/src/juejin/lc/hot100/AddTwoNumbers.java create mode 100644 java/src/juejin/lc/hot100/LengthOfLongestSubstring.java create mode 100644 java/src/juejin/lc/hot100/LongestPalindrome.java create mode 100644 java/src/juejin/lc/hot100/MaxSubArray.java create mode 100644 java/src/juejin/lc/hot100/TwoSum.java diff --git a/java/src/juejin/lc/hot100/AddTwoNumbers.java b/java/src/juejin/lc/hot100/AddTwoNumbers.java new file mode 100644 index 0000000..2e34c64 --- /dev/null +++ b/java/src/juejin/lc/hot100/AddTwoNumbers.java @@ -0,0 +1,51 @@ +package juejin.lc.hot100; + +public class AddTwoNumbers { + /** + * 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的, + * 并且它们的每个节点只能存储 一位 数字。 + * 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 + * 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 + * + * 示例: + * + * 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) + * 输出:7 -> 0 -> 8 + * 原因:342 + 465 = 807 + * @param l1 + * @param l2 + * @return + */ + public ListNode solution(ListNode l1, ListNode l2) { + ListNode resNode = new ListNode(0); + ListNode curr = resNode; + int index = 0; + while (null != l1 || null != l2) { + int x = null != l1 ? l1.val : 0; + int y = null != l2 ? l2.val : 0; + int sum = x + y + index; + index = sum / 10; + curr.next = new ListNode(sum % 10); + curr = curr.next; + if (null != l1) { + l1 = l1.next; + } + if (null != l2) { + l2 = l2.next; + } + } + if (index > 0) { + curr.next = new ListNode(index); + } + return resNode.next; + } + + public class ListNode { + int val; + ListNode next; + + ListNode(int x) { + val = x; + } + } +} diff --git a/java/src/juejin/lc/hot100/LengthOfLongestSubstring.java b/java/src/juejin/lc/hot100/LengthOfLongestSubstring.java new file mode 100644 index 0000000..b15bfae --- /dev/null +++ b/java/src/juejin/lc/hot100/LengthOfLongestSubstring.java @@ -0,0 +1,45 @@ +package juejin.lc.hot100; + +import java.util.HashSet; +import java.util.Set; + +public class LengthOfLongestSubstring { + /** + * 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 + *

+ * 示例 1: + * 输入: "abcabcbb" + * 输出: 3 + * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 + *

+ * 示例 2: + * 输入: "bbbbb" + * 输出: 1 + * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 + *

+ * 示例 3: + * 输入: "pwwkew" + * 输出: 3 + * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 + *   请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 + * + * @param s + * @return + */ + public int solution(String s) { + Set set = new HashSet<>(); + int n = s.length(); + int rk = -1,ans = 0; + for (int i = 0; i < n; i++) { + if (i != 0) { + set.remove(s.charAt(i - 1)); + } + while (rk + 1 < n && !set.contains(s.charAt(rk + 1))) { + set.add(s.charAt(rk + 1)); + ++rk; + } + ans = Math.max(ans, rk - i + 1); + } + return ans; + } +} diff --git a/java/src/juejin/lc/hot100/LongestPalindrome.java b/java/src/juejin/lc/hot100/LongestPalindrome.java new file mode 100644 index 0000000..065bc44 --- /dev/null +++ b/java/src/juejin/lc/hot100/LongestPalindrome.java @@ -0,0 +1,83 @@ +package juejin.lc.hot100; + +public class LongestPalindrome { + /** + * 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 + *

+ * 示例 1: + * 输入: "babad" + * 输出: "bab" + * 注意: "aba" 也是一个有效答案。 + *

+ * 示例 2: + * 输入: "cbbd" + * 输出: "bb" + * + * @param s + * @return + */ + public String solution(String s) { + // 动态规划 + // 边界条件 + int n = s.length(); + if (n < 2) { + return s; + } + char[] chars = s.toCharArray(); + int begin = 0; + int offset = 1; + boolean[][] dp = new boolean[n][n]; + for (int i = 0; i < n; i++) { + dp[i][i] = true; + } + for (int i = 0; i < n - 1; i++) { + for (int j = i + 1; j < n; j++) { + if (chars[i] != chars[j]) { + dp[i][j] = false; + } else { + if (j - i < 3) { + dp[i][j] = dp[i + 1][j - 1]; + } + } + if (dp[i][j] && j - i + 1 > offset) { + begin = i; + offset = j - i + 1; + } + } + } + return s.substring(begin, begin + offset); + } + + public String solution1(String s) { + // 暴力破解法 + // 边界条件 + int n = s.length(); + if (n < 2) { + return s; + } + char[] chars = s.toCharArray(); + int begin = 0; + int offset = 1; + for (int i = 0; i < n - 1; i++) { + for (int j = i + 1; j < n; j++) { + if (j - i + 1 > offset && isPalindrome(chars, i, j)) { + begin = i; + offset = j - i + 1; + } + } + } + return s.substring(begin, begin + offset); + } + + public boolean isPalindrome(char[] chars, int begin, int end) { + // 边界条件 不考虑 begin >= end 情况 + while (begin < end) { + if (chars[begin] != chars[end]) { + return false; + } + ++begin; + --end; + } + return true; + } +} diff --git a/java/src/juejin/lc/hot100/MaxSubArray.java b/java/src/juejin/lc/hot100/MaxSubArray.java new file mode 100644 index 0000000..0369a95 --- /dev/null +++ b/java/src/juejin/lc/hot100/MaxSubArray.java @@ -0,0 +1,47 @@ +package juejin.lc.hot100; + +public class MaxSubArray { + /** + * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 + *

+ * 示例: + *

+ * 输入: [-2,1,-3,4,-1,2,1,-5,4] + * 输出: 6 + * 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 + * + * @param nums + * @return + */ + public int solution(int[] nums) { + int[] dp = new int[nums.length]; + dp[0] = nums[0]; + for (int i = 1; i < nums.length; i++) { + if (dp[i - 1] > 0) { + dp[i] = dp[i - 1] + nums[i]; + } else { + dp[i] = nums[i]; + } + } + int res = dp[0]; + for (int i = 1; i < dp.length; i++) { + if (dp[i] > res) { + res = dp[i]; + } + } + return res; + } + + public int solution1(int[] nums) { + // 边界条件 + int sum = 0; + int res = nums[0]; + for (int i = 0; i < nums.length; i++) { + sum = sum > 0 ? sum + nums[i] : nums[i]; + if (res < sum) { + res = sum; + } + } + return res; + } +} diff --git a/java/src/juejin/lc/hot100/TwoSum.java b/java/src/juejin/lc/hot100/TwoSum.java new file mode 100644 index 0000000..b429027 --- /dev/null +++ b/java/src/juejin/lc/hot100/TwoSum.java @@ -0,0 +1,33 @@ +package juejin.lc.hot100; + +import java.util.HashMap; +import java.util.Map; + +public class TwoSum { + /** + * 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 + * 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。 + * 说明: + * 返回的下标值(index1 和 index2)不是从零开始的。 + * 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 + * 示例: + * 输入: numbers = [2, 7, 11, 15], target = 9 + * 输出: [1,2] + * 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 + * + * @param nums 数组 + * @param target 目标值 + * @return 返回数组 + */ + public int[] solution(int[] nums, int target) { + Map map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + int cur = target - nums[i]; + if (map.containsKey(cur)) { + return new int[]{map.get(cur), i}; + } + map.put(nums[i], i); + } + throw new Error("error"); + } +} diff --git a/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java b/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java index e78d5a7..635cb90 100644 --- a/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java +++ b/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java @@ -21,7 +21,8 @@ public class LengthOfLongestSubstring { public static int lengthOfLongestSubstring(String s) { int n = s.length(), ans = 0; - Map map = new HashMap<>(); // current index of character + // current index of character + Map map = new HashMap<>(); // try to extend the range [i, j] for (int j = 0, i = 0; j < n; j++) { if (map.containsKey(s.charAt(j))) { From d6f793f7434cc4a3c84f674a1df0b7c5282b52f7 Mon Sep 17 00:00:00 2001 From: liuchao <1054415232@qq.com> Date: Tue, 11 Apr 2023 17:48:24 +0800 Subject: [PATCH 43/43] =?UTF-8?q?Feat:=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 42 +++ .../lc/dynamicProgramming/BackPack01.java | 2 +- .../LongestCommonSequence.java | 27 +- .../LongestCommonSubString.java | 11 +- .../LongestIncreasingSubSequence.java | 10 +- .../dynamicProgramming/MaxSubsequenceSum.java | 22 +- java/src/juejin/lc/hot100/AddTwoNumbers.java | 5 +- .../lc/hot100/LengthOfLongestSubstring.java | 2 +- java/src/juejin/lc/leetCode/AddBinary.java | 2 +- java/src/juejin/lc/leetCode/AddDigits.java | 5 +- .../src/juejin/lc/leetCode/AddTwoNumbers.java | 183 ++++++----- java/src/juejin/lc/leetCode/ArrangeCoins.java | 7 +- .../juejin/lc/leetCode/BinaryTreePaths.java | 26 +- java/src/juejin/lc/leetCode/CanWinNim.java | 6 +- java/src/juejin/lc/leetCode/ClimbStairs.java | 18 +- .../lc/leetCode/ContainsNearbyDuplicate.java | 4 +- java/src/juejin/lc/leetCode/CountAndSay.java | 3 +- java/src/juejin/lc/leetCode/CountPrimes.java | 25 +- .../juejin/lc/leetCode/DeleteDuplicates.java | 6 +- java/src/juejin/lc/leetCode/DeleteNode.java | 38 ++- .../juejin/lc/leetCode/FindTheDifference.java | 4 +- .../juejin/lc/leetCode/FirstBadVersion.java | 4 +- java/src/juejin/lc/leetCode/FizzBuzz.java | 48 +-- java/src/juejin/lc/leetCode/GetSum.java | 1 + .../src/juejin/lc/leetCode/HammingWeight.java | 4 +- java/src/juejin/lc/leetCode/HasCycle.java | 9 +- java/src/juejin/lc/leetCode/HasPathSum.java | 25 +- java/src/juejin/lc/leetCode/IntToRoman.java | 9 +- java/src/juejin/lc/leetCode/InvertTree.java | 36 ++- .../lc/leetCode/IowestCommonAncestor.java | 37 ++- java/src/juejin/lc/leetCode/IsAnagram.java | 19 +- java/src/juejin/lc/leetCode/IsHappy.java | 11 +- java/src/juejin/lc/leetCode/IsIsomorphic.java | 17 +- java/src/juejin/lc/leetCode/IsPowerOfTwo.java | 13 +- java/src/juejin/lc/leetCode/IsSymmetric.java | 34 +- java/src/juejin/lc/leetCode/IsUgly.java | 13 +- .../lc/leetCode/IsValidParentheses.java | 19 +- .../juejin/lc/leetCode/LengthOfLastWord.java | 2 +- .../lc/leetCode/LengthOfLongestSubstring.java | 20 +- java/src/juejin/lc/leetCode/LevelOrder.java | 27 +- .../juejin/lc/leetCode/LongestPalindrome.java | 19 +- .../lc/leetCode/LongestPalindromeLength.java | 2 +- .../juejin/lc/leetCode/MajorityElement.java | 11 +- .../juejin/lc/leetCode/MaxNumberMatrix.java | 1 + java/src/juejin/lc/leetCode/MaxProfit.java | 299 +++++++++++++++++- java/src/juejin/lc/leetCode/Merge.java | 11 +- java/src/juejin/lc/leetCode/MinDepth.java | 1 - java/src/juejin/lc/leetCode/MinStack.java | 2 +- .../src/juejin/lc/leetCode/MissingNumber.java | 2 +- java/src/juejin/lc/leetCode/MyQueue.java | 21 +- java/src/juejin/lc/leetCode/MyStack.java | 29 +- .../lc/leetCode/NarcissisticNumber.java | 5 +- .../lc/leetCode/NumberOfBoomerangs.java | 32 ++ .../src/juejin/lc/leetCode/NumberReverse.java | 12 +- java/src/juejin/lc/leetCode/PlusOne.java | 4 +- .../juejin/lc/leetCode/RemoveDuplicates.java | 4 +- .../src/juejin/lc/leetCode/RemoveElement.java | 12 +- .../juejin/lc/leetCode/RemoveElements.java | 60 ++-- java/src/juejin/lc/leetCode/ReverseList.java | 41 ++- java/src/juejin/lc/leetCode/SearchInsert.java | 12 +- .../juejin/lc/leetCode/SortedArrayToBST.java | 6 +- .../juejin/lc/leetCode/StrStrSolution.java | 5 +- .../juejin/lc/leetCode/SumOfLeftLeaves.java | 19 +- java/src/juejin/lc/leetCode/ToHex.java | 9 +- java/src/juejin/lc/leetCode/TwoNum.java | 49 ++- java/src/juejin/lc/leetCode/TwoSum.java | 22 +- java/src/juejin/lc/other/IdWorker.java | 1 + java/src/juejin/lc/sorts/BaseSort.java | 3 +- java/src/juejin/lc/sql/MergeTwoTable.sql | 20 +- java/src/juejin/lc/sql/TheSecondSalary.sql | 71 +++-- java/src/juejin/lc/string/Pattern.java | 10 +- 71 files changed, 1061 insertions(+), 530 deletions(-) create mode 100644 java/src/juejin/lc/leetCode/NumberOfBoomerangs.java diff --git a/README.md b/README.md index 73cb335..f73aece 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,85 @@ # Progress Every Day + ## LeetCode => [地址](https://github.com/chaoaiqi/study/tree/master/java/src/juejin/lc/leetCode) + ## 传送门 + ### [01背包](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/BackPack01.java) + ### [最大子序列和](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java) + ### [最长递增子序列](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java) + ### [最长公共子串](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java) + ### [最长公共子序列](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java) + ### [正则表达式匹配算法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/Pattern.java) + ### [AVL树](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/tree/AVLTree.java) + ### [N皇后](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/leetCode/SolveNQueens.java) + ### [基于AC自动机的敏感词匹配系统](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/tree/AhoCorasick.java) + ### [统计字符串中某一单词出现的频率](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/tree/TrieTreeAlgo.java) + ### [简易Trie树](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/tree/TrieTree.java) + ### [循环链表](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/linkedList/CircleLinkList.java) + ### [双向链表](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/linkedList/DulLinkList.java) + ### [KMP算法(基于DFA)](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/KMPByDFA.java) + ### [KMP算法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/KMPArithmetic.java) + ### [BM启发式算法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/BoyerMoore.java) + ### [BM算法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/BMArithmetic.java) + ### [RK算法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/RKArithmetic.java) + ### [BF算法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/string/BFArithmetic.java) + ### [基于无向图的bfs和dfs](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/graph/Graph.java) + ### [求一组动态数据集合的最大 Top K](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/leetCode/GetTopKArrays.java) + ### [堆的实现及求一组动态数据的中位数](https://github.com/chaoaiqi/study/tree/master/java/src/juejin/lc/heap) + ### [单链表回文](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/leetCode/Palindrome.java) + ### [二叉树的遍历](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/tree/TraversalTree.java) + ### [二叉搜索树](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/tree/BinarySearchTree.java) + ### [散列表的两种实现](https://github.com/chaoaiqi/study/tree/master/java/src/juejin/lc/hashTable) + ### [跳表的实现](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/linkedList/SkipList.java) + ### [LRU缓存淘汰算法的两种实现](https://github.com/chaoaiqi/study/tree/master/java/src/juejin/lc/lruAlgo) + ### [求一个正整数的平方根](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/leetCode/SqrtSolution.java) + ### [二分查找](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/search/BinarySearch.java) + ### [ 使用快排实现在O(n)内查找一个无序数组的第K大元素](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/leetCode/FindKthLargest.java) + ### [程序员必会的五个排序](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/sorts/BaseSort.java) + ### [斐波那契数列的四种实现方法](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/recursion/Recursion.java) + ### [队列的三种实现](https://github.com/chaoaiqi/study/tree/master/java/src/juejin/lc/queue) + ### [基于栈的简易计算器](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/stack/SimpleCalculator.java) + ### [栈的实现](https://github.com/chaoaiqi/study/tree/master/java/src/juejin/lc/stack) + ### [关于单链表的五道题](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/linkedList/LinkedListAlgo.java) + ### [单链表的插入,删除,查询](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/linkedList/SinglyLinkedList.java) + ### [两个有序数组合并为一个有序数组](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/arithmetic/MergeArrays.java) + ### [数组的实现](https://github.com/chaoaiqi/study/blob/master/java/src/juejin/lc/arithmetic/Array.java) \ No newline at end of file diff --git a/java/src/juejin/lc/dynamicProgramming/BackPack01.java b/java/src/juejin/lc/dynamicProgramming/BackPack01.java index ba42afe..66a5fb7 100644 --- a/java/src/juejin/lc/dynamicProgramming/BackPack01.java +++ b/java/src/juejin/lc/dynamicProgramming/BackPack01.java @@ -56,7 +56,7 @@ private void situation(int[] items, int[] v, int[] p, int[][] dp, int i, int j) situation(items, v, p, dp, i - 1, j); } else if (j - v[i] >= 0 && dp[i][j] == dp[i - 1][j - v[i]] + p[i]) { items[i] = 1; - situation(items, v, p, dp, i - 1, j -v[i]); + situation(items, v, p, dp, i - 1, j - v[i]); } } } diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java index 33fb23c..49ce422 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSequence.java @@ -12,6 +12,7 @@ public class LongestCommonSequence { /** * s1 = “abcbdab”;s2 = "bdcaba"。 * 4 + * * @param s1 string * @param s2 string * @return 返回最长公共子序列长度 @@ -34,25 +35,25 @@ private int solution(String s1, String s2) { char[] str2 = s2.toCharArray(); int[][] dp = new int[str1.length][str2.length]; for (int i = 0; i < str1.length; i++) { - if (str1[i] == str2[0]){ + if (str1[i] == str2[0]) { dp[i][0] = 1; - }else{ + } else { dp[i][0] = 0; } } for (int j = 0; j < str2.length; j++) { - if (str2[j] == str1[0]){ + if (str2[j] == str1[0]) { dp[0][j] = 1; - }else{ + } else { dp[0][j] = 0; } } for (int i = 1; i < str1.length; i++) { for (int j = 1; j < str2.length; j++) { - if (str1[i] == str2[j]){ - dp[i][j] = dp[i-1][j-1] +1; - }else{ - dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]); + if (str1[i] == str2[j]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]); } } } @@ -64,22 +65,24 @@ private int solution(String s1, String s2) { if (dp[i][j] == length && stringBuilder.indexOf(String.valueOf(str1[i])) == -1) { stringBuilder.append(str1[i]); } - length = Math.max(length,dp[i][j]); + length = Math.max(length, dp[i][j]); } } System.out.println(stringBuilder.reverse().toString()); return length; } + private void print(int[][] dp) { for (int[] ds : dp) { System.out.println(Arrays.toString(ds)); } } + public static void main(String[] args) { LongestCommonSequence longestCommonSubString = new LongestCommonSequence(); - String s1 = "abcbdab"; - String s2 = "bdcaba"; - int res = longestCommonSubString.solution(s1,s2); + String s1 = "你啊"; + String s2 = "你好啊"; + int res = longestCommonSubString.solution(s1, s2); System.out.println(res); } } diff --git a/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java b/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java index f020b28..58fd640 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestCommonSubString.java @@ -70,9 +70,11 @@ private String solution(String str1, String str2) { max = dp[i][j]; y = i; x = j; + System.out.println(max + "," + x + "," + y); } } } + System.out.println("====================="); System.out.println(max + "," + x + "," + y); return resJoint(str1, x, y); @@ -81,7 +83,7 @@ private String solution(String str1, String str2) { /** * 优化 * 根据解法1可以找到规律,求最长公共子串可以转换为求二阶矩阵的最大递增对角线问题 - * b d c a b a + * b d c a b a * a [0, 0, 0, 1, 0, 1] * b [1, 0, 0, 0, 2, 0] * c [0, 0, 1, 0, 0, 0] @@ -150,9 +152,8 @@ private String resJoint(String str, int x, int y) { public static void main(String[] args) { LongestCommonSubString longestCommonSubString = new LongestCommonSubString(); - String s1 = "abcbdab"; - String s2 = "bdcaba"; - String res = longestCommonSubString.solution2(s1, s2); - System.out.println("最长公共子串为:" + res); + System.out.println(longestCommonSubString.solution( + "hhh刘璐琪#&#开黑的小姐姐#&#李贵人鸟是啥#&#架构师#&#全栈开发", + "架构师#&#全栈开发")); } } diff --git a/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java b/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java index 7edb624..2ec0f33 100644 --- a/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java +++ b/java/src/juejin/lc/dynamicProgramming/LongestIncreasingSubSequence.java @@ -2,6 +2,7 @@ /** * 最长递增子序列 + * * @author liuchao * @date 2019/6/19 */ @@ -9,10 +10,11 @@ public class LongestIncreasingSubSequence { /** * 最长递增子序列(Longest Increasing Subsequence)是指找到一个给定序列的最长子序列的长度,使得子序列中的所有元素单调递增。 * 例如:{ 3,5,7,1,2,8 } 的 LIS 是 { 3,5,7,8 },长度为 4。 + * * @param nums 数组 * @return 返回长度 */ - private int solution(int[] nums){ + private int solution(int[] nums) { //推公式 //F[i] = max{1,F[j]+1|aj max) { + if (F[i] > max) { max = F[i]; } System.out.println("F[" + i + "] = " + F[i]); @@ -38,7 +40,7 @@ private int solution(int[] nums){ } public static void main(String[] args) { - int[] nums = { 3,5,7,1,2,8 }; + int[] nums = {3, 5, 7, 1, 2, 8}; int res = new LongestIncreasingSubSequence().solution(nums); System.out.println(res); } diff --git a/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java b/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java index 06c5c76..81d810c 100644 --- a/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java +++ b/java/src/juejin/lc/dynamicProgramming/MaxSubsequenceSum.java @@ -2,48 +2,50 @@ /** * 最大子序列和 + * * @author liuchao * @date 2019/6/19 */ public class MaxSubsequenceSum { /** - * * @param nums 传入数组 * @return 返回值 */ - private int solution(int[] nums){ + private int solution(int[] nums) { // 状态转移方程公式 // dp[0] = ai; (i = 0) // dp[i] = dp[i-1]>=0 ? dp[i-1]+nums[i] : nums[i] (i > 1) int[] dp = new int[nums.length]; dp[0] = nums[0]; for (int i = 1; i < nums.length; i++) { - if(dp[i - 1] >= 0) { + if (dp[i - 1] >= 0) { dp[i] = dp[i - 1] + nums[i]; - }else { + } else { dp[i] = nums[i]; } - System.out.println("dp[" + i + "] = " + dp[i]); + System.out.println("dp[" + i + "] = " + dp[i]); } // 取dp里面最大值即可 int res = dp[0]; for (int i = 1; i < dp.length; i++) { - if(dp[i] > res) { + if (dp[i] > res) { res = dp[i]; } } return res; } + /** * 最优解 + * * @param nums 传入数组 * @return 返回值 */ - private int solution2(int[] nums){ + private int solution2(int[] nums) { int res = nums[0]; int sum = 0; - for(int num: nums) { - if(sum > 0) { + for (int num : nums) { + if (sum > 0) { sum += num; } else { sum = num; @@ -54,7 +56,7 @@ private int solution2(int[] nums){ } public static void main(String[] args) { - int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; + int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; int res = new MaxSubsequenceSum().solution(nums); System.out.println("最大子序列和为:" + res); } diff --git a/java/src/juejin/lc/hot100/AddTwoNumbers.java b/java/src/juejin/lc/hot100/AddTwoNumbers.java index 2e34c64..ef0d28a 100644 --- a/java/src/juejin/lc/hot100/AddTwoNumbers.java +++ b/java/src/juejin/lc/hot100/AddTwoNumbers.java @@ -6,12 +6,13 @@ public class AddTwoNumbers { * 并且它们的每个节点只能存储 一位 数字。 * 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 * 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 - * + *

* 示例: - * + *

* 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) * 输出:7 -> 0 -> 8 * 原因:342 + 465 = 807 + * * @param l1 * @param l2 * @return diff --git a/java/src/juejin/lc/hot100/LengthOfLongestSubstring.java b/java/src/juejin/lc/hot100/LengthOfLongestSubstring.java index b15bfae..86d58b8 100644 --- a/java/src/juejin/lc/hot100/LengthOfLongestSubstring.java +++ b/java/src/juejin/lc/hot100/LengthOfLongestSubstring.java @@ -29,7 +29,7 @@ public class LengthOfLongestSubstring { public int solution(String s) { Set set = new HashSet<>(); int n = s.length(); - int rk = -1,ans = 0; + int rk = -1, ans = 0; for (int i = 0; i < n; i++) { if (i != 0) { set.remove(s.charAt(i - 1)); diff --git a/java/src/juejin/lc/leetCode/AddBinary.java b/java/src/juejin/lc/leetCode/AddBinary.java index 6692282..2a57531 100644 --- a/java/src/juejin/lc/leetCode/AddBinary.java +++ b/java/src/juejin/lc/leetCode/AddBinary.java @@ -43,6 +43,6 @@ public static void main(String[] args) { AddBinary addBinary = new AddBinary(); String a = "1010"; String b = "1011"; - System.out.println(addBinary.solution(a,b)); + System.out.println(addBinary.solution(a, b)); } } diff --git a/java/src/juejin/lc/leetCode/AddDigits.java b/java/src/juejin/lc/leetCode/AddDigits.java index 74f035c..8d0fc78 100644 --- a/java/src/juejin/lc/leetCode/AddDigits.java +++ b/java/src/juejin/lc/leetCode/AddDigits.java @@ -3,9 +3,9 @@ public class AddDigits { /** * 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。 - * + *

* 示例: - * + *

* 输入: 38 * 输出: 2 * 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。 @@ -27,6 +27,7 @@ private int solution(int num) { } return sum; } + private int optimalSolution(int num) { return (num - 1) % 9 + 1; } diff --git a/java/src/juejin/lc/leetCode/AddTwoNumbers.java b/java/src/juejin/lc/leetCode/AddTwoNumbers.java index dbc9e0a..1061349 100644 --- a/java/src/juejin/lc/leetCode/AddTwoNumbers.java +++ b/java/src/juejin/lc/leetCode/AddTwoNumbers.java @@ -5,112 +5,111 @@ /** * 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 单位 数字。 - * + *

* 如果,我们将这两个数起来相加起来,则会返回出一个新的链表来表示它们的和。 - * + *

* 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 - * + *

* 示例: - * + *

* 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 - * - * @author liuchao * + * @author liuchao */ public class AddTwoNumbers { - public ListNode addTwoNumbers(ListNode l1, ListNode l2) { - ListNode dummyHead = new ListNode(0); - ListNode p = l1, q = l2, curr = dummyHead; - int carry = 0; - while (p != null || q != null) { - int x = (null != p) ? p.val : 0; - int y = (null != q) ? q.val : 0; - int sum = carry + x + y; - carry = sum / 10; - curr.next = new ListNode(sum % 10); - curr = curr.next; - if (null != p) - p = p.next; - if (null != q) - q = q.next; - } - if (carry > 0) { - curr.next = new ListNode(carry); - } - return dummyHead.next; - } + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + ListNode dummyHead = new ListNode(0); + ListNode p = l1, q = l2, curr = dummyHead; + int carry = 0; + while (p != null || q != null) { + int x = (null != p) ? p.val : 0; + int y = (null != q) ? q.val : 0; + int sum = carry + x + y; + carry = sum / 10; + curr.next = new ListNode(sum % 10); + curr = curr.next; + if (null != p) + p = p.next; + if (null != q) + q = q.next; + } + if (carry > 0) { + curr.next = new ListNode(carry); + } + return dummyHead.next; + } - public void initListNode() { - ListNode l1 = new ListNode(1); + public void initListNode() { + ListNode l1 = new ListNode(1); // l1.next = new ListNode(8); - ListNode l2 = new ListNode(9); - l2.next = new ListNode(9); + ListNode l2 = new ListNode(9); + l2.next = new ListNode(9); - List list = new ArrayList(); - boolean sign = false; - while (null != l1 || null != l2) { - int sum = 0; - if (null == l1) { - sum = l2.val; - } else if (null == l2) { - sum = l1.val; - } else { - sum = l1.val + l2.val; - } - int val = sum >= 10 ? sum - 10 : sum; - if (sign) { - sign = false; - if (val + 1 >= 10) { - sign = true; - } - val = val + 1 >= 10 ? val + 1 - 10 : val + 1; - } - if (sum >= 10) { - sign = true; - } - list.add(val); - if (null != l1) - l1 = l1.next; - if (null != l2) - l2 = l2.next; - } - if (sign) { - list.add(1); - } - ListNode listNode = null; - for (int i = list.size() - 1; i >= 0; i--) { - System.out.println(list.get(i)); - ListNode node = new ListNode(list.get(i)); - if (null == listNode) { - listNode = node; - } else { - node.next = listNode; - listNode = node; - } - } - while (null != listNode) { - System.out.print(listNode.val); - if (listNode.next != null) - System.out.print("-"); - listNode = listNode.next; - } - } + List list = new ArrayList(); + boolean sign = false; + while (null != l1 || null != l2) { + int sum = 0; + if (null == l1) { + sum = l2.val; + } else if (null == l2) { + sum = l1.val; + } else { + sum = l1.val + l2.val; + } + int val = sum >= 10 ? sum - 10 : sum; + if (sign) { + sign = false; + if (val + 1 >= 10) { + sign = true; + } + val = val + 1 >= 10 ? val + 1 - 10 : val + 1; + } + if (sum >= 10) { + sign = true; + } + list.add(val); + if (null != l1) + l1 = l1.next; + if (null != l2) + l2 = l2.next; + } + if (sign) { + list.add(1); + } + ListNode listNode = null; + for (int i = list.size() - 1; i >= 0; i--) { + System.out.println(list.get(i)); + ListNode node = new ListNode(list.get(i)); + if (null == listNode) { + listNode = node; + } else { + node.next = listNode; + listNode = node; + } + } + while (null != listNode) { + System.out.print(listNode.val); + if (listNode.next != null) + System.out.print("-"); + listNode = listNode.next; + } + } - public static void main(String[] args) { - new AddTwoNumbers().initListNode(); - } + public static void main(String[] args) { + new AddTwoNumbers().initListNode(); + } - public class ListNode { - public int val; - ListNode next; + public class ListNode { + public int val; + ListNode next; - ListNode() { + ListNode() { - } + } - ListNode(int x) { - this.val = x; - } - } + ListNode(int x) { + this.val = x; + } + } } diff --git a/java/src/juejin/lc/leetCode/ArrangeCoins.java b/java/src/juejin/lc/leetCode/ArrangeCoins.java index c0b2639..ae34290 100644 --- a/java/src/juejin/lc/leetCode/ArrangeCoins.java +++ b/java/src/juejin/lc/leetCode/ArrangeCoins.java @@ -5,7 +5,7 @@ public class ArrangeCoins { * 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。 * 给定一个数字 n,找出可形成完整阶梯行的总行数。 * n 是一个非负整数,并且在32位有符号整型的范围内。 - * + *

* 示例 1: * n = 5 * 硬币可排列成以下几行: @@ -13,7 +13,7 @@ public class ArrangeCoins { * ¤ ¤ * ¤ ¤ * 因为第三行不完整,所以返回2. - * + *

* 示例 2: * n = 8 * 硬币可排列成以下几行: @@ -22,12 +22,13 @@ public class ArrangeCoins { * ¤ ¤ ¤ * ¤ ¤ * 因为第四行不完整,所以返回3. + * * @param n * @return */ public int solution(int n) { // 边界条件 - if(n < 0) { + if (n < 0) { return 0; } if (n == 1) { diff --git a/java/src/juejin/lc/leetCode/BinaryTreePaths.java b/java/src/juejin/lc/leetCode/BinaryTreePaths.java index 66c2ee6..1971306 100644 --- a/java/src/juejin/lc/leetCode/BinaryTreePaths.java +++ b/java/src/juejin/lc/leetCode/BinaryTreePaths.java @@ -9,14 +9,15 @@ public class BinaryTreePaths { * 说明: 叶子节点是指没有子节点的节点。 * 示例: * 输入: - * - * 1 - * / \ + *

+ * 1 + * / \ * 2 3 - * \ - * 5 + * \ + * 5 * 输出: ["1->2->5", "1->3"] * 解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3 + * * @param root 二叉树 * @return 二叉树的所有路径 */ @@ -27,18 +28,19 @@ private List solution(TreeNode root) { } private void constructPaths(TreeNode root, String path, LinkedList paths) { - if (null != root){ + if (null != root) { path += Integer.toString(root.val); - if (null == root.left && null == root.right){ + if (null == root.left && null == root.right) { paths.add(path); - }else { + } else { path += "->"; constructPaths(root.left, path, paths); constructPaths(root.right, path, paths); } } } - private TreeNode createTreeNode(){ + + private TreeNode createTreeNode() { TreeNode node = new TreeNode(1); TreeNode node1 = new TreeNode(2); TreeNode node2 = new TreeNode(3); @@ -47,11 +49,15 @@ private TreeNode createTreeNode(){ node1.right = new TreeNode(5); return node; } + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } public static void main(String[] args) { diff --git a/java/src/juejin/lc/leetCode/CanWinNim.java b/java/src/juejin/lc/leetCode/CanWinNim.java index ddb8a45..2e10539 100644 --- a/java/src/juejin/lc/leetCode/CanWinNim.java +++ b/java/src/juejin/lc/leetCode/CanWinNim.java @@ -4,11 +4,11 @@ public class CanWinNim { /** * 你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 * 拿掉最后一块石头的人就是获胜者。你作为先手。 - * + *

* 你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。 - * + *

* 示例: - * + *

* 输入: 4 * 输出: false * 解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛; diff --git a/java/src/juejin/lc/leetCode/ClimbStairs.java b/java/src/juejin/lc/leetCode/ClimbStairs.java index 48e6e29..b1dbde2 100644 --- a/java/src/juejin/lc/leetCode/ClimbStairs.java +++ b/java/src/juejin/lc/leetCode/ClimbStairs.java @@ -7,16 +7,17 @@ * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? * 注意:给定 n 是一个正整数。 + * * @author liuchao * @date 2019/5/24 */ public class ClimbStairs { - public int solution(int n){ - int[] arrs = new int[n + 1]; - return recursion(arrs,n); + public int solution(int n) { + int[] arrs = new int[n + 1]; + return recursion(arrs, n); } - public int climbStairs2(int n){ + public int climbStairs2(int n) { if (n == 1) { return 1; } @@ -29,14 +30,15 @@ public int climbStairs2(int n){ } return arrs[n]; } + private int recursion(int[] arrs, int n) { - if (n < 3){ + if (n < 3) { return n; } - if (arrs[n] > 0){ + if (arrs[n] > 0) { return arrs[n]; - }else{ - arrs[n] = recursion(arrs,n - 1) + recursion(arrs,n - 2); + } else { + arrs[n] = recursion(arrs, n - 1) + recursion(arrs, n - 2); } return arrs[n]; } diff --git a/java/src/juejin/lc/leetCode/ContainsNearbyDuplicate.java b/java/src/juejin/lc/leetCode/ContainsNearbyDuplicate.java index 38581fd..3d9c076 100644 --- a/java/src/juejin/lc/leetCode/ContainsNearbyDuplicate.java +++ b/java/src/juejin/lc/leetCode/ContainsNearbyDuplicate.java @@ -37,7 +37,7 @@ private boolean solution(int[] nums, int k) { set.add(nums[i]); System.out.println("size = " + set.size() + ",k = " + k); if (set.size() > k) { - System.out.println("nums[" + i + " - " + k + "] = " + nums[i - k]); + System.out.println("nums[" + i + " - " + k + "] = " + nums[i - k]); set.remove(nums[i - k]); } System.out.println("set = " + set.toString()); @@ -61,7 +61,7 @@ private boolean solution1(int[] nums, int k) { public static void main(String[] args) { ContainsNearbyDuplicate containsNearbyDuplicate = new ContainsNearbyDuplicate(); - int[] nums = {1,0,1,1}; + int[] nums = {1, 0, 1, 1}; int k = 3; boolean result = containsNearbyDuplicate.solution(nums, k); System.out.println("result = " + result); diff --git a/java/src/juejin/lc/leetCode/CountAndSay.java b/java/src/juejin/lc/leetCode/CountAndSay.java index ee00b2a..ad4ee48 100644 --- a/java/src/juejin/lc/leetCode/CountAndSay.java +++ b/java/src/juejin/lc/leetCode/CountAndSay.java @@ -5,6 +5,7 @@ * 11 被读作 "two 1" ("两个一"), 即 21。 * 21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。 * #TODO 迷迷糊糊 + * * @author liuchao * @date 2019/5/24 */ @@ -36,7 +37,7 @@ private String countAndSay(int n) { int check = 1; char c = temp.charAt(0); for (int i = 1; i < temp.length(); i++) { - System.out.println("check = " + check + ",c = " + c + ",temp[" + i + "] = " + temp.charAt(i)); + System.out.println("check = " + check + ",c = " + c + ",temp[" + i + "] = " + temp.charAt(i)); if (temp.charAt(i) == c) { check++; continue; diff --git a/java/src/juejin/lc/leetCode/CountPrimes.java b/java/src/juejin/lc/leetCode/CountPrimes.java index bbda844..1239b57 100644 --- a/java/src/juejin/lc/leetCode/CountPrimes.java +++ b/java/src/juejin/lc/leetCode/CountPrimes.java @@ -5,12 +5,13 @@ public class CountPrimes { /** * 统计所有小于非负整数 n 的质数的数量。 - * + *

* 示例: - * + *

* 输入: 10 * 输出: 4 * 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。 + * * @param n 输入 * @return 输出 */ @@ -20,41 +21,43 @@ private int solution(int n) { Arrays.fill(isPrim, true); for (int i = 2; i * i < n; i++) { - if (isPrim[i]){ - for (int j = i * i; j < n; j+=i) { + if (isPrim[i]) { + for (int j = i * i; j < n; j += i) { System.out.println("j = " + j); isPrim[j] = false; } } } int count = 0; - for (int i = 2; i * 示例 1: - * + *

* 输入: head = [4,5,1,9], node = 5 * 输出: [4,1,9] * 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. * 示例 2: - * + *

* 输入: head = [4,5,1,9], node = 1 * 输出: [4,5,9] * 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9. *   * 说明: - * + *

* 链表至少包含两个节点。 * 链表中所有节点的值都是唯一的。 * 给定的节点为非末尾节点并且一定是链表中的一个有效节点。 * 不要从你的函数中返回任何结果。 - + * * @param node 节点 */ private void solution(ListNode node) { @@ -35,27 +36,33 @@ private void solution(ListNode node) { /** * 常规删除链表指定节点,与题目无关 + * * @param node 节点 */ private void solution1(ListNode node) { ListNode headNode = head; - if (headNode.val == node.val){ + if (headNode.val == node.val) { headNode = headNode.next; } - while (null != headNode.next && null != headNode.next.next){ - if (headNode.next.val == node.val){ + while (null != headNode.next && null != headNode.next.next) { + if (headNode.next.val == node.val) { headNode.next = headNode.next.next; - }else { + } else { headNode = headNode.next; } } } + public class ListNode { int val; ListNode next; - ListNode(int x) { val = x; } + + ListNode(int x) { + val = x; + } } - private ListNode createHead(){ + + private ListNode createHead() { ListNode node1 = new ListNode(4); ListNode node2 = new ListNode(5); ListNode node3 = new ListNode(1); @@ -65,24 +72,27 @@ private ListNode createHead(){ node3.next = node4; return node1; } - private ListNode createNode(){ + + private ListNode createNode() { ListNode node3 = new ListNode(1); ListNode node4 = new ListNode(9); node3.next = node4; return node3; } + private void print() { ListNode listNode = head; - while (null != listNode){ + while (null != listNode) { int val = listNode.val; System.out.print(val); - if (null != listNode.next){ + if (null != listNode.next) { System.out.print("->"); } listNode = listNode.next; } System.out.println(); } + public static void main(String[] args) { DeleteNode deleteNode = new DeleteNode(); deleteNode.head = deleteNode.createHead(); diff --git a/java/src/juejin/lc/leetCode/FindTheDifference.java b/java/src/juejin/lc/leetCode/FindTheDifference.java index 8c94a11..dc6c24f 100644 --- a/java/src/juejin/lc/leetCode/FindTheDifference.java +++ b/java/src/juejin/lc/leetCode/FindTheDifference.java @@ -32,7 +32,7 @@ public class FindTheDifference { * @return res */ private char solution(String s, String t) { - char difference = 0; + char difference = 0; for (int i = 0; i < s.length(); i++) { difference ^= s.charAt(i); } @@ -46,7 +46,7 @@ public static void main(String[] args) { String s = "abcd"; String t = "abcde"; FindTheDifference findTheDifference = new FindTheDifference(); - char res = findTheDifference.solution(s,t); + char res = findTheDifference.solution(s, t); System.out.println("res = " + res); } } diff --git a/java/src/juejin/lc/leetCode/FirstBadVersion.java b/java/src/juejin/lc/leetCode/FirstBadVersion.java index 956e4dc..14069cc 100644 --- a/java/src/juejin/lc/leetCode/FirstBadVersion.java +++ b/java/src/juejin/lc/leetCode/FirstBadVersion.java @@ -29,9 +29,9 @@ private int solution(int n) { int right = n; while (left < right) { int mid = left + (right - left) / 2; - if (isBadVersion(mid)){ + if (isBadVersion(mid)) { right = mid; - }else { + } else { left = mid + 1; } } diff --git a/java/src/juejin/lc/leetCode/FizzBuzz.java b/java/src/juejin/lc/leetCode/FizzBuzz.java index 2c1d0c6..cb16873 100644 --- a/java/src/juejin/lc/leetCode/FizzBuzz.java +++ b/java/src/juejin/lc/leetCode/FizzBuzz.java @@ -6,41 +6,42 @@ public class FizzBuzz { /** * 写一个程序,输出从 1 到 n 数字的字符串表示。 - * + *

* 1. 如果 n 是3的倍数,输出“Fizz”; - * + *

* 2. 如果 n 是5的倍数,输出“Buzz”; - * + *

* 3.如果 n 同时是3和5的倍数,输出 “FizzBuzz”。 - * + *

* 示例: - * + *

* n = 15, - * + *

* 返回: * [ - * "1", - * "2", - * "Fizz", - * "4", - * "Buzz", - * "Fizz", - * "7", - * "8", - * "Fizz", - * "Buzz", - * "11", - * "Fizz", - * "13", - * "14", - * "FizzBuzz" + * "1", + * "2", + * "Fizz", + * "4", + * "Buzz", + * "Fizz", + * "7", + * "8", + * "Fizz", + * "Buzz", + * "11", + * "Fizz", + * "13", + * "14", + * "FizzBuzz" * ] + * * @param n * @return */ public List solution(int n) { if (n <= 0) { - return new ArrayList<>(); + return new ArrayList<>(); } List list = new ArrayList<>(); for (int i = 1; i <= n; i++) { @@ -69,9 +70,10 @@ public List solution(int n) { } return list; } + public List solution1(int n) { if (n <= 0) { - return new ArrayList<>(); + return new ArrayList<>(); } List list = new ArrayList<>(); for (int i = 1; i <= n; i++) { diff --git a/java/src/juejin/lc/leetCode/GetSum.java b/java/src/juejin/lc/leetCode/GetSum.java index 6b9c951..d9c9a7d 100644 --- a/java/src/juejin/lc/leetCode/GetSum.java +++ b/java/src/juejin/lc/leetCode/GetSum.java @@ -13,6 +13,7 @@ public class GetSum { * 输入: a = -2, b = 3 * 输出: 1 * TODO + * * @param a 整数 a * @param b 整数 b * @return 整数和 diff --git a/java/src/juejin/lc/leetCode/HammingWeight.java b/java/src/juejin/lc/leetCode/HammingWeight.java index 37b6b76..e49a4d9 100644 --- a/java/src/juejin/lc/leetCode/HammingWeight.java +++ b/java/src/juejin/lc/leetCode/HammingWeight.java @@ -1,11 +1,11 @@ package juejin.lc.leetCode; public class HammingWeight { - public int solution(int n){ + public int solution(int n) { String str = Integer.toBinaryString(n); int num = 0; for (int i = 0; i < str.length(); i++) { - if (str.charAt(i) == '1'){ + if (str.charAt(i) == '1') { ++num; } } diff --git a/java/src/juejin/lc/leetCode/HasCycle.java b/java/src/juejin/lc/leetCode/HasCycle.java index 878af08..831fdce 100644 --- a/java/src/juejin/lc/leetCode/HasCycle.java +++ b/java/src/juejin/lc/leetCode/HasCycle.java @@ -29,15 +29,15 @@ public class HasCycle { * @return 返回值 */ private boolean solution(ListNode head) { - if (null == head || null == head.next){ - return false; + if (null == head || null == head.next) { + return false; } ListNode slow = head; ListNode fast = head.next; - while (null != fast && null != fast.next){ + while (null != fast && null != fast.next) { slow = slow.next; fast = fast.next.next; - if (slow == fast){ + if (slow == fast) { return true; } } @@ -47,6 +47,7 @@ private boolean solution(ListNode head) { private class ListNode { int val; ListNode next; + ListNode(int x) { val = x; next = null; diff --git a/java/src/juejin/lc/leetCode/HasPathSum.java b/java/src/juejin/lc/leetCode/HasPathSum.java index 4848652..d90c155 100644 --- a/java/src/juejin/lc/leetCode/HasPathSum.java +++ b/java/src/juejin/lc/leetCode/HasPathSum.java @@ -2,6 +2,7 @@ /** * 路径总和 + * * @author liuchao * @date 2019/5/29 */ @@ -11,27 +12,29 @@ public class HasPathSum { * 说明: 叶子节点是指没有子节点的节点。 * 示例: * 给定如下二叉树,以及目标和 sum = 22, - * 5 - * / \ - * 4 8 - * / / \ - * 11 13 4 - * / \ \ - * 7 2 1 + * 5 + * / \ + * 4 8 + * / / \ + * 11 13 4 + * / \ \ + * 7 2 1 * 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。 + * * @param root 二叉树 - * @param sum 路径总和 + * @param sum 路径总和 * @return 返回结果 */ public boolean solution(TreeNode root, int sum) { - if (null == root){ + if (null == root) { return false; } - if (null == root.left && null == root.right){ + if (null == root.left && null == root.right) { return sum - root.val == 0; } - return solution(root.left,sum - root.val) || solution(root.right,sum - root.val); + return solution(root.left, sum - root.val) || solution(root.right, sum - root.val); } + private static class TreeNode { int val; TreeNode left; diff --git a/java/src/juejin/lc/leetCode/IntToRoman.java b/java/src/juejin/lc/leetCode/IntToRoman.java index 3a5c013..5b1616a 100644 --- a/java/src/juejin/lc/leetCode/IntToRoman.java +++ b/java/src/juejin/lc/leetCode/IntToRoman.java @@ -2,17 +2,18 @@ /** * 整数转罗马数字 + * * @author liuchao * @date 2019/5/23 */ public class IntToRoman { public String intToRoman(int num) { - int values[]={1000,900,500,400,100,90,50,40,10,9,5,4,1}; - String reps[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; + int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; + String reps[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; String res = ""; - for(int i=0; i<13; i++){ - while(num>=values[i]){ + for (int i = 0; i < 13; i++) { + while (num >= values[i]) { num -= values[i]; res += reps[i]; } diff --git a/java/src/juejin/lc/leetCode/InvertTree.java b/java/src/juejin/lc/leetCode/InvertTree.java index 642c0dc..6e15c7d 100644 --- a/java/src/juejin/lc/leetCode/InvertTree.java +++ b/java/src/juejin/lc/leetCode/InvertTree.java @@ -9,22 +9,22 @@ public class InvertTree { /** * 翻转一棵二叉树。 - * + *

* 示例: - * + *

* 输入: - * - * 4 - * / \ - * 2 7 - * / \ / \ + *

+ * 4 + * / \ + * 2 7 + * / \ / \ * 1 3 6 9 * 输出: - * - * 4 - * / \ - * 7 2 - * / \ / \ + *

+ * 4 + * / \ + * 7 2 + * / \ / \ * 9 6 3 1 * * @param root 二叉树 @@ -39,7 +39,8 @@ private TreeNode solution(TreeNode root) { root.right = left; return root; } - private TreeNode createTreeNode(){ + + private TreeNode createTreeNode() { TreeNode treeNode = new TreeNode(4); TreeNode treeNode1 = new TreeNode(2); TreeNode treeNode2 = new TreeNode(7); @@ -55,19 +56,24 @@ private TreeNode createTreeNode(){ treeNode2.right = treeNode6; return treeNode; } + private void preOrderTraversal(TreeNode tree) { - if (null == tree){ + if (null == tree) { return; } System.out.print(tree.val + " "); preOrderTraversal(tree.left); preOrderTraversal(tree.right); } + public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } public static void main(String[] args) { diff --git a/java/src/juejin/lc/leetCode/IowestCommonAncestor.java b/java/src/juejin/lc/leetCode/IowestCommonAncestor.java index ce8e177..1382111 100644 --- a/java/src/juejin/lc/leetCode/IowestCommonAncestor.java +++ b/java/src/juejin/lc/leetCode/IowestCommonAncestor.java @@ -3,66 +3,71 @@ public class IowestCommonAncestor { /** * 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 - * + *

* 百度百科中最近公共祖先的定义为: * “对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大 * (一个节点也可以是它自己的祖先)。” * 例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5] - * + *

* 示例 1: - * + *

* 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 * 输出: 6 * 解释: 节点 2 和节点 8 的最近公共祖先是 6。 * 示例 2: - * + *

* 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 * 输出: 2 * 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。 *   - * + *

* 说明: - * + *

* 所有节点的值都是唯一的。 * p、q 为不同节点且均存在于给定的二叉搜索树中。 * * @param root 二叉树 - * @param p 二叉树子节点 - * @param q 二叉树子节点 + * @param p 二叉树子节点 + * @param q 二叉树子节点 * @return 节点树 */ public TreeNode solution(TreeNode root, TreeNode p, TreeNode q) { int rootVal = root.val; - int pVal = p.val; + int pVal = p.val; int qVal = q.val; if (pVal > rootVal && qVal > rootVal) { - return solution(root.right,p,q); - }else if(pVal < rootVal && qVal < rootVal) { - return solution(root.left,p,q); + return solution(root.right, p, q); + } else if (pVal < rootVal && qVal < rootVal) { + return solution(root.left, p, q); } return root; } + public TreeNode solution1(TreeNode root, TreeNode p, TreeNode q) { - int pVal = p.val; + int pVal = p.val; int qVal = q.val; TreeNode node = root; while (null != node) { int rootVal = node.val; if (pVal > rootVal && qVal > rootVal) { node = node.right; - }else if(pVal < rootVal && qVal < rootVal) { + } else if (pVal < rootVal && qVal < rootVal) { node = node.left; - }else { + } else { return node; } } return node; } + public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } public static void main(String[] args) { diff --git a/java/src/juejin/lc/leetCode/IsAnagram.java b/java/src/juejin/lc/leetCode/IsAnagram.java index 676b52f..46be5f8 100644 --- a/java/src/juejin/lc/leetCode/IsAnagram.java +++ b/java/src/juejin/lc/leetCode/IsAnagram.java @@ -7,13 +7,13 @@ public class IsAnagram { /** * 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 - * + *

* 示例 1: - * + *

* 输入: s = "anagram", t = "nagaram" * 输出: true * 示例 2: - * + *

* 输入: s = "rat", t = "car" * 输出: false * 说明: @@ -31,17 +31,18 @@ private boolean solution(String s, String t) { char[] t1 = t.toCharArray(); Arrays.sort(s1); Arrays.sort(t1); - return Arrays.equals(s1,t1); + return Arrays.equals(s1, t1); } /** * 高阶解法 + * * @param s 字符串 * @param t 字符串 * @return r */ private boolean solution1(String s, String t) { - if(s.length() != t.length()){ + if (s.length() != t.length()) { return false; } int[] counter = new int[26]; @@ -49,15 +50,16 @@ private boolean solution1(String s, String t) { ++counter[s.charAt(i) - 'a']; --counter[t.charAt(i) - 'a']; } - for (int count: counter) { + for (int count : counter) { if (count != 0) { return false; } } return true; } + private boolean solution2(String s, String t) { - if(s.length() != t.length()){ + if (s.length() != t.length()) { return false; } int[] table = new int[26]; @@ -72,11 +74,12 @@ private boolean solution2(String s, String t) { } return true; } + public static void main(String[] args) { IsAnagram isAnagram = new IsAnagram(); String s = "anagram"; String t = "nagram"; - boolean result = isAnagram.solution(s,t); + boolean result = isAnagram.solution(s, t); System.out.println("result = " + result); } } diff --git a/java/src/juejin/lc/leetCode/IsHappy.java b/java/src/juejin/lc/leetCode/IsHappy.java index 0375bf5..06e3daf 100644 --- a/java/src/juejin/lc/leetCode/IsHappy.java +++ b/java/src/juejin/lc/leetCode/IsHappy.java @@ -11,6 +11,7 @@ */ public class IsHappy { private Map map = new HashMap(); + /** * 一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1, * 也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。 @@ -33,24 +34,24 @@ private boolean solution(int n) { slow = recursion(slow); fast = recursion(fast); fast = recursion(fast); - }while (slow != fast); + } while (slow != fast); return fast == 1; } - private int recursion(int n){ + private int recursion(int n) { int sum = 0; - while (n != 0){ + while (n != 0) { int num = n % 10; sum += num * num; n /= 10; } - return sum; + return sum; } public static void main(String[] args) { int n = 2; IsHappy isHappy = new IsHappy(); - boolean res = isHappy.solution(n); + boolean res = isHappy.solution(n); System.out.println("res = " + res); } } diff --git a/java/src/juejin/lc/leetCode/IsIsomorphic.java b/java/src/juejin/lc/leetCode/IsIsomorphic.java index 40ed4bb..97ca454 100644 --- a/java/src/juejin/lc/leetCode/IsIsomorphic.java +++ b/java/src/juejin/lc/leetCode/IsIsomorphic.java @@ -9,23 +9,24 @@ public class IsIsomorphic { /** * 给定两个字符串 s 和 t,判断它们是否是同构的。 - * + *

* 如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。 - * + *

* 所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。 - * + *

* 示例 1: - * + *

* 输入: s = "egg", t = "add" * 输出: true * 示例 2: - * + *

* 输入: s = "foo", t = "bar" * 输出: false * 示例 3: - * + *

* 输入: s = "paper", t = "title" * 输出: true + * * @param s 输入字符串 * @param t 输入字符串 * @return 输出结果 @@ -34,7 +35,7 @@ private boolean solution(String s, String t) { char[] chars = s.toCharArray(); char[] chart = t.toCharArray(); for (int i = 0; i < s.length(); i++) { - if (s.indexOf(chars[i]) != t.indexOf(chart[i])){ + if (s.indexOf(chars[i]) != t.indexOf(chart[i])) { return false; } } @@ -45,7 +46,7 @@ public static void main(String[] args) { IsIsomorphic isIsomorphic = new IsIsomorphic(); String s = "foo"; String t = "add"; - boolean result = isIsomorphic.solution(s,t); + boolean result = isIsomorphic.solution(s, t); System.out.println("result = " + result); } } diff --git a/java/src/juejin/lc/leetCode/IsPowerOfTwo.java b/java/src/juejin/lc/leetCode/IsPowerOfTwo.java index 85cba95..0ccb8e4 100644 --- a/java/src/juejin/lc/leetCode/IsPowerOfTwo.java +++ b/java/src/juejin/lc/leetCode/IsPowerOfTwo.java @@ -3,26 +3,26 @@ public class IsPowerOfTwo { /** * 给定一个整数,编写一个函数来判断它是否是 2 的幂次方。 - * + *

* 示例 1: - * + *

* 输入: 1 * 输出: true * 解释: 20 = 1 * 示例 2: - * + *

* 输入: 16 * 输出: true * 解释: 24 = 16 * 示例 3: - * + *

* 输入: 218 * 输出: false * * @param n 指定整数 * @return 是否是2的幂次方 */ - private boolean solution(int n){ + private boolean solution(int n) { // 若 n = 2^x // x且 x 为自然数(即 n 为 2 的幂),则一定满足以下条件: // 恒有 n & (n - 1) == 0,这是因为: @@ -32,7 +32,8 @@ private boolean solution(int n){ // 因此,通过 n > 0 且 n & (n - 1) == 0 即可判定是否满足 n = 2^x return n > 0 && (n & (n - 1)) == 0; } - private boolean solution1(int n){ + + private boolean solution1(int n) { return n > 0 && (n & -n) == n; } } diff --git a/java/src/juejin/lc/leetCode/IsSymmetric.java b/java/src/juejin/lc/leetCode/IsSymmetric.java index 5c9e016..d3c1e88 100644 --- a/java/src/juejin/lc/leetCode/IsSymmetric.java +++ b/java/src/juejin/lc/leetCode/IsSymmetric.java @@ -10,33 +10,35 @@ */ public class IsSymmetric { /** - *例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 - * 1 - * / \ - * 2 2 - * / \ / \ + * 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 + * 1 + * / \ + * 2 2 + * / \ / \ * 3 4 4 3 * 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: - * 1 - * / \ - * 2 2 - * \ \ - * 3 3 + * 1 + * / \ + * 2 2 + * \ \ + * 3 3 + * * @param root 二叉树 * @return 返回结果 */ private boolean solution(TreeNode root) { - if (null == root){ + if (null == root) { return true; } - return traversal(root.left,root.right); + return traversal(root.left, root.right); } - private boolean traversal(TreeNode left,TreeNode right){ - if (null == left && right == null){ + + private boolean traversal(TreeNode left, TreeNode right) { + if (null == left && right == null) { return true; } - if (null != left && null != right && left.val == right.val){ - return traversal(left.left,right.right) && traversal(left.right,right.left); + if (null != left && null != right && left.val == right.val) { + return traversal(left.left, right.right) && traversal(left.right, right.left); } return false; } diff --git a/java/src/juejin/lc/leetCode/IsUgly.java b/java/src/juejin/lc/leetCode/IsUgly.java index 31db1c9..faffa22 100644 --- a/java/src/juejin/lc/leetCode/IsUgly.java +++ b/java/src/juejin/lc/leetCode/IsUgly.java @@ -3,28 +3,29 @@ public class IsUgly { /** * 判断给定的数是否为丑数。 - * + *

* 丑数就是只包含质因数 2, 3, 5 的正整数。 - * + *

* 示例 1: - * + *

* 输入: 6 * 输出: true * 解释: 6 = 2 × 3 * 示例 2: - * + *

* 输入: 8 * 输出: true * 解释: 8 = 2 × 2 × 2 * 示例 3: - * + *

* 输入: 14 * 输出: false * 解释: 14 不是丑数,因为它包含了另外一个质因数 7。 * 说明: - * + *

* 1 是丑数。 * 输入不会超过 32 位有符号整数的范围: [−2^31,  2^31 − 1]。 + * * @param num 数 * @return 返回结果 */ diff --git a/java/src/juejin/lc/leetCode/IsValidParentheses.java b/java/src/juejin/lc/leetCode/IsValidParentheses.java index 30b1e35..4a70c67 100644 --- a/java/src/juejin/lc/leetCode/IsValidParentheses.java +++ b/java/src/juejin/lc/leetCode/IsValidParentheses.java @@ -24,15 +24,15 @@ public boolean isValid(String s) { Stack stack = new Stack<>(); char[] chars = s.toCharArray(); for (char c : chars) { - if (stack.isEmpty()){ - stack.push(c); - }else if (checkFull(stack.peek(),c)){ - stack.pop(); - }else{ - stack.push(c); - } + if (stack.isEmpty()) { + stack.push(c); + } else if (checkFull(stack.peek(), c)) { + stack.pop(); + } else { + stack.push(c); + } } - if (stack.isEmpty()){ + if (stack.isEmpty()) { return true; } return false; @@ -40,7 +40,8 @@ public boolean isValid(String s) { /** * 校验是否完整 - * @param prev 栈里的 + * + * @param prev 栈里的 * @param current 当前 * @return 返回结果 */ diff --git a/java/src/juejin/lc/leetCode/LengthOfLastWord.java b/java/src/juejin/lc/leetCode/LengthOfLastWord.java index 692a950..5b970fc 100644 --- a/java/src/juejin/lc/leetCode/LengthOfLastWord.java +++ b/java/src/juejin/lc/leetCode/LengthOfLastWord.java @@ -39,7 +39,7 @@ private int solution2(String s) { for (int i = s.length() - 1; i >= 0; i--) { if (s.charAt(i) != ' ') { ++count; - }else if (count != 0){ + } else if (count != 0) { return count; } } diff --git a/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java b/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java index 635cb90..84d9c8d 100644 --- a/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java +++ b/java/src/juejin/lc/leetCode/LengthOfLongestSubstring.java @@ -5,18 +5,17 @@ /** * 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 - * + *

* 示例 1: - * + *

* 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2: - * + *

* 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 示例 3: - * + *

* 输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 * 的长度,"pwke" 是一个子序列,不是子串。 - * - * @author liuchao * + * @author liuchao */ public class LengthOfLongestSubstring { public static int lengthOfLongestSubstring(String s) { @@ -33,9 +32,10 @@ public static int lengthOfLongestSubstring(String s) { } return ans; } + public static void main(String[] args) { - System.out.println(lengthOfLongestSubstring( "abcabcbb")); - System.out.println(lengthOfLongestSubstring( "bbbbb")); - System.out.println(lengthOfLongestSubstring( "pwwkew")); - } + System.out.println(lengthOfLongestSubstring("abcabcbb")); + System.out.println(lengthOfLongestSubstring("bbbbb")); + System.out.println(lengthOfLongestSubstring("pwwkew")); + } } diff --git a/java/src/juejin/lc/leetCode/LevelOrder.java b/java/src/juejin/lc/leetCode/LevelOrder.java index 20d5f4f..1bfb8fe 100644 --- a/java/src/juejin/lc/leetCode/LevelOrder.java +++ b/java/src/juejin/lc/leetCode/LevelOrder.java @@ -7,23 +7,23 @@ public class LevelOrder { /** * 给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。 - * + *

*   - * + *

* 示例: * 二叉树:[3,9,20,null,null,15,7], - * - * 3 - * / \ - * 9 20 - * / \ - * 15 7 + *

+ * 3 + * / \ + * 9 20 + * / \ + * 15 7 * 返回其层次遍历结果: - * + *

* [ - * [3], - * [9,20], - * [15,7] + * [3], + * [9,20], + * [15,7] * ] * * @param root @@ -54,7 +54,8 @@ public List> solution(TreeNode root) { list.add(child); } return list; -} + } + public class TreeNode { int val; TreeNode left; diff --git a/java/src/juejin/lc/leetCode/LongestPalindrome.java b/java/src/juejin/lc/leetCode/LongestPalindrome.java index 9ac5785..630a0d0 100644 --- a/java/src/juejin/lc/leetCode/LongestPalindrome.java +++ b/java/src/juejin/lc/leetCode/LongestPalindrome.java @@ -2,21 +2,21 @@ /** * 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 - * + *

* 示例 1: - * + *

* 输入: "babad" * 输出: "bab" * 注意: "aba" 也是一个有效答案。 * 示例 2: - * + *

* 输入: "cbbd" * 输出: "bb" - * */ public class LongestPalindrome { /** * 动态规划 + * * @param s * @return */ @@ -40,11 +40,11 @@ public String solution1(String s) { } else { if (j - i < 3) { dp[i][j] = true; - } else { + } else { dp[i][j] = dp[i + 1][j - 1]; } } - if (dp[i][j] && j - i + 1> offset) { + if (dp[i][j] && j - i + 1 > offset) { offset = j - i + 1; begin = i; } @@ -52,8 +52,10 @@ public String solution1(String s) { } return s.substring(begin, begin + offset); } + /** - * 暴力破解法 + * 暴力破解法 + * * @param s 字符串 * @return 最长回文串 */ @@ -69,7 +71,7 @@ public String solution(String s) { int offset = 1; for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { - if (j - i + 1 > offset && isPalindrome(chars, i,j)) { + if (j - i + 1 > offset && isPalindrome(chars, i, j)) { begin = i; offset = j - i + 1; } @@ -77,6 +79,7 @@ public String solution(String s) { } return s.substring(begin, begin + offset); } + public boolean isPalindrome(char[] chars, int begin, int end) { // 边界条件 不考虑 begin >= end 情况 while (begin < end) { diff --git a/java/src/juejin/lc/leetCode/LongestPalindromeLength.java b/java/src/juejin/lc/leetCode/LongestPalindromeLength.java index aaa0bb1..ca34cff 100644 --- a/java/src/juejin/lc/leetCode/LongestPalindromeLength.java +++ b/java/src/juejin/lc/leetCode/LongestPalindromeLength.java @@ -31,7 +31,7 @@ public int solution(String s) { ++chars[c]; } int ans = 0; - for (int v: chars) { + for (int v : chars) { // 忽略奇数 ans += v / 2 * 2; // 填充奇数 diff --git a/java/src/juejin/lc/leetCode/MajorityElement.java b/java/src/juejin/lc/leetCode/MajorityElement.java index 45b2b2c..017fe01 100644 --- a/java/src/juejin/lc/leetCode/MajorityElement.java +++ b/java/src/juejin/lc/leetCode/MajorityElement.java @@ -29,16 +29,15 @@ public int solution(int[] nums) { int ret = nums[0]; System.out.println("nums[0] = " + ret); int count = 1; - for(int num : nums) { + for (int num : nums) { System.out.println("num = " + num + ", ret = " + ret + ", count = " + count); - if(num != ret) { + if (num != ret) { count--; - if(count == 0) { + if (count == 0) { count = 1; ret = num; } - } - else{ + } else { count++; } } @@ -58,7 +57,7 @@ public int solutiont(int[] nums) { public static void main(String[] args) { MajorityElement majorityElement = new MajorityElement(); - int[] nums = {3,2,3,1,5,1,4,1,1}; + int[] nums = {3, 2, 3, 1, 5, 1, 4, 1, 1}; int res = majorityElement.solution(nums); System.out.println(res); } diff --git a/java/src/juejin/lc/leetCode/MaxNumberMatrix.java b/java/src/juejin/lc/leetCode/MaxNumberMatrix.java index 4eec90e..3c89bab 100644 --- a/java/src/juejin/lc/leetCode/MaxNumberMatrix.java +++ b/java/src/juejin/lc/leetCode/MaxNumberMatrix.java @@ -4,6 +4,7 @@ public class MaxNumberMatrix { /** * 给定一个非空二维矩阵 matrix 和一个整数 k,找到这个矩阵内部不大于 k 的最大矩形和。 * TODO + * * @param matrix 二维矩阵 * @param k 整数 * @return 最大矩形和 diff --git a/java/src/juejin/lc/leetCode/MaxProfit.java b/java/src/juejin/lc/leetCode/MaxProfit.java index 03242a7..d08f2f2 100644 --- a/java/src/juejin/lc/leetCode/MaxProfit.java +++ b/java/src/juejin/lc/leetCode/MaxProfit.java @@ -1,5 +1,9 @@ package juejin.lc.leetCode; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + /** * 买入股票的最佳时机 * @@ -65,7 +69,7 @@ public int solution(int[] prices) { private int solution2(int[] prices) { int maxProfit = 0; for (int i = 1; i < prices.length; i++) { - if (prices[i] - prices[i - 1] > 0){ + if (prices[i] - prices[i - 1] > 0) { maxProfit += prices[i] - prices[i - 1]; } System.out.println("prices[i] - prices[i - 1] = " + (prices[i] - prices[i - 1])); @@ -73,11 +77,296 @@ private int solution2(int[] prices) { return maxProfit; } + /** + * 暴力破解法超出时间限制 + * + * @param prices + * @return + */ + private int solution3(int[] prices) { + int maxProfit = 0; + for (int i = 0; i < prices.length - 1; i++) { + for (int j = i + 1; j < prices.length; j++) { + int curProfit = prices[j] - prices[i]; +// System.out.println("i = " + i + ", j = " + j + ", curProfit = " + curProfit); + if (maxProfit < curProfit) { + maxProfit = curProfit; + } + } + } + return maxProfit; + } + + /** + * 归约法 + * + * @param prices + * @return + */ + private int solution4(int[] prices) { + int[] profits = new int[prices.length - 1]; + for (int i = 1; i < prices.length; i++) { + profits[i - 1] = prices[i] - prices[i - 1]; + } + // 转成成求最大子序列和 + System.out.println(Arrays.toString(profits)); + int sum = 0; + int maxProfits = 0; + for (int i = 0; i < profits.length; i++) { + sum = sum > 0 ? sum + profits[i] : profits[i]; + System.out.println("i = " + i + ", sum = " + sum + ", maxProfits = " + maxProfits); + if (maxProfits < sum) { + maxProfits = sum; + } + } + return maxProfits; + } + + /** + * 贪心法 + * + * @param prices + * @return + */ + private int solution5(int[] prices) { + int minPrices = prices[0]; + int maxProfit = 0; + for (int i = 1; i < prices.length; i++) { + minPrices = Math.min(minPrices, prices[i]); + maxProfit = Math.max(maxProfit, prices[i] - minPrices); + System.out.println("i = " + i + ", minPrices = " + minPrices + ", maxProfit = " + maxProfit); + } + + return maxProfit; + } + + /** + * 贪心法2 + * + * @param prices + * @return + */ + private int solution6(int[] prices) { + int minPrices = prices[0]; + int maxProfit = 0; + for (int i = 1; i < prices.length; i++) { + int profit = prices[i] - minPrices; + if (profit > maxProfit) { + maxProfit = profit; + } + if (profit < 0) { + minPrices = prices[i]; + } + } + + return maxProfit; + } + + /** + * 动态规划 + * + * @param prices + * @return + */ + private int solution7(int[] prices) { + //buyIn[i]表示第i天第最低最低买入价; + //saleOut[i]表示第i天第最大收益; + //第i天的最大收益,要么就是第i-1的收益,要么就是用第i天的价格卖出buyIn[i-1]买入的价格 + int[] buyIn = new int[prices.length]; + int[] saleOut = new int[prices.length]; + + buyIn[0] = prices[0]; + saleOut[0] = 0; + for (int i = 1; i < prices.length; i++) { + saleOut[i] = Math.max(prices[i] - buyIn[i - 1], saleOut[i - 1]); + buyIn[i] = Math.min(prices[i], buyIn[i - 1]); + } + return Math.max(saleOut[prices.length - 1], 0); + } + + /** + * 动规变形 + * + * @param prices + * @return + */ + private int solution8(int[] prices) { + int[] deltaPrices = new int[prices.length - 1]; + for (int i = 0; i < deltaPrices.length; i++) { + deltaPrices[i] = prices[i + 1] - prices[i]; + } + int maxProfit = maxSubArray(deltaPrices); + return Math.max(maxProfit, 0); + } + + private int maxSubArray(int[] deltaPrices) { + int maxSum = Integer.MIN_VALUE; + int sum = 0; + for (int i = 0; i < deltaPrices.length; i++) { + sum += deltaPrices[i]; + if (sum > maxSum) { + maxSum = sum; + } + //思想来自DP,如果一个sum为负,无论nums[i+1]是什么,那么nums[i+1]一定比nums[i+1]+sum大; + //因此可以找到从i+1开始新的子数组; + if (sum < 0) { + sum = 0; + } + //假设我们现在的sum就是maxSum,那么下一个数是一个负数,加入sum之后,sum变小了,但sum>0; + } + + return maxSum; + } + + private int solution9(int[] prices) { + return Math.max(maxSubArrayProfit(prices, 0, prices.length - 1), 0); + } + + private int maxSubArrayProfit(int[] prices, int left, int right) { + int arrayLength = right - left + 1; + if (arrayLength <= 3) { + int maxProfit = 0; + for (int i = left; i < right; i++) { + for (int j = i + 1; j < arrayLength; j++) { + int profit = prices[j] - prices[i]; + maxProfit = Math.max(maxProfit, profit); + } + } + return maxProfit; + } + //[0,1,2,3,4,5,6], (5-4)/2 + 4 = 4. 因此midIndex,也就是说midIndex+1永远有意义,如果left mid + 1) { + rightMax = getMaxNumber(prices, mid + 1, right); + } else { + rightMax = prices[mid + 1]; + } + return rightMax - leftMin; + } + + private int getMaxNumber(int[] prices, int start, int end) { + int maxSum = Integer.MIN_VALUE; + for (int i = start; i < end; i++) { + if (maxSum <= prices[i]) { + maxSum = prices[i]; + } + } + return maxSum; + } + + private int getMinNumber(int[] prices, int start, int end) { + int minSum = Integer.MAX_VALUE; + for (int i = start; i < end; i++) { + if (minSum > prices[i]) { + minSum = prices[i]; + } + } + return minSum; + } + + private int solution10(int[] prices) { + MinMaxStack minStack = new MinMaxStack(); + MinMaxStack maxStack = new MinMaxStack(); + int maxProfit = 0; + int minPrice = prices[0]; + minStack.push(minPrice); + + for (int i = prices.length - 1; i > 0; i--) { + maxStack.push(prices[i]); + } + System.out.println("maxStack: " + maxStack); + for (int i = 1; i < prices.length; i++) { + int profit = maxStack.getMax() - minStack.getMin(); + if (profit > maxProfit) { + maxProfit = profit; + } + int price = maxStack.remove(); + System.out.println("i = " + i + ", maxStack: " + maxStack); + minStack.push(price); + } + return maxProfit; + } + + + class MinMaxStack { + List stack; + List minStack; + List maxStack; + + public MinMaxStack() { + stack = new LinkedList<>(); + minStack = new LinkedList<>(); + maxStack = new LinkedList<>(); + } + + public void push(int x) { + stack.add(x); + int maxStackValue = Integer.MIN_VALUE; + int minStackValue = Integer.MAX_VALUE; + if (minStack.size() > 0) { + minStackValue = minStack.get(minStack.size() - 1); + } + if (maxStack.size() > 0) { + maxStackValue = maxStack.get(maxStack.size() - 1); + } + minStack.add(Math.min(minStackValue, x)); + maxStack.add(Math.max(maxStackValue, x)); + } + + public void pop() { + stack.remove(stack.size() - 1); + minStack.remove(minStack.size() - 1); + maxStack.remove(maxStack.size() - 1); + } + + public int remove() { + minStack.remove(minStack.size() - 1); + maxStack.remove(maxStack.size() - 1); + return stack.remove(stack.size() - 1); + } + + public int top() { + return stack.get(minStack.size() - 1); + } + + public int getMin() { + return minStack.get(minStack.size() - 1); + } + + public int getMax() { + return maxStack.get(maxStack.size() - 1); + } + + @Override + public String toString() { + return "MinMaxStack{" + + "stack=" + stack + + ", minStack=" + minStack + + ", maxStack=" + maxStack + + '}'; + } + } + public static void main(String[] args) { - int[] prices = {1,2,3,4,5}; -// int[] prices = {7, 1, 5, 3, 6, 4}; MaxProfit maxProfit = new MaxProfit(); - int res = maxProfit.solution2(prices); - System.out.println(res); + int[] prices3 = {7, 1, 5, 3, 6, 4}; + System.out.println(maxProfit.solution10(prices3)); } } diff --git a/java/src/juejin/lc/leetCode/Merge.java b/java/src/juejin/lc/leetCode/Merge.java index dabbebc..4bad2c6 100644 --- a/java/src/juejin/lc/leetCode/Merge.java +++ b/java/src/juejin/lc/leetCode/Merge.java @@ -6,16 +6,17 @@ public class Merge { /** * 给出一个区间的集合,请合并所有重叠的区间。 - * + *

* 示例 1: * 输入: intervals = [[1,3],[2,6],[8,10],[15,18]] * 输出: [[1,6],[8,10],[15,18]] * 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. - * + *

* 示例 2: * 输入: intervals = [[1,4],[4,5]] * 输出: [[1,5]] * 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。 + * * @param intervals * @return */ @@ -26,10 +27,10 @@ public static int[][] solution(int[][] intervals) { // 遍历区间 int[][] res = new int[intervals.length][2]; int idx = -1; - for (int[] interval: intervals) { + for (int[] interval : intervals) { // 如果结果数组是空的,或者当前区间的起始位置> 结果数组的最后区间的终止位置 // 则不合并、 - if(idx == -1 || interval[0] > res[idx][1]) { + if (idx == -1 || interval[0] > res[idx][1]) { res[++idx] = interval; } else { // 反之将当前区间合并至结果数组的最后区间 @@ -41,7 +42,7 @@ public static int[][] solution(int[][] intervals) { } public static void main(String[] args) { - int[][] nums = {{1,3},{2,6},{8,10},{15,18}}; + int[][] nums = {{1, 3}, {2, 6}, {8, 10}, {15, 18}}; int[][] res = solution(nums); System.out.println(Arrays.deepToString(res)); } diff --git a/java/src/juejin/lc/leetCode/MinDepth.java b/java/src/juejin/lc/leetCode/MinDepth.java index f0119c8..c830c55 100644 --- a/java/src/juejin/lc/leetCode/MinDepth.java +++ b/java/src/juejin/lc/leetCode/MinDepth.java @@ -9,7 +9,6 @@ */ public class MinDepth { /** - * * @param root 二叉树 * @return 最小深度 */ diff --git a/java/src/juejin/lc/leetCode/MinStack.java b/java/src/juejin/lc/leetCode/MinStack.java index 7894a9f..c7e4e64 100644 --- a/java/src/juejin/lc/leetCode/MinStack.java +++ b/java/src/juejin/lc/leetCode/MinStack.java @@ -71,7 +71,7 @@ public static void main(String[] args) { // System.out.println("----------------------"); // System.out.println("length= " + minStack.stack.size()); int min = minStack.getMin(); - System.out.println("最小值:" + min); + System.out.println("最小值:" + min); minStack.pop(); int top = minStack.top(); System.out.println("top:" + top); diff --git a/java/src/juejin/lc/leetCode/MissingNumber.java b/java/src/juejin/lc/leetCode/MissingNumber.java index dbac082..3dc9c0f 100644 --- a/java/src/juejin/lc/leetCode/MissingNumber.java +++ b/java/src/juejin/lc/leetCode/MissingNumber.java @@ -73,7 +73,7 @@ private int solution1(int[] nums) { public static void main(String[] args) { MissingNumber missingNumber = new MissingNumber(); - int[] nums = {0,1}; + int[] nums = {0, 1}; // int[] nums = {9, 6, 4, 2, 3, 5, 7, 0, 1}; int result = missingNumber.solution2(nums); System.out.println("result = " + result); diff --git a/java/src/juejin/lc/leetCode/MyQueue.java b/java/src/juejin/lc/leetCode/MyQueue.java index 791d730..72ff50d 100644 --- a/java/src/juejin/lc/leetCode/MyQueue.java +++ b/java/src/juejin/lc/leetCode/MyQueue.java @@ -5,13 +5,18 @@ public class MyQueue { private Stack stack; private Stack baseStack; - /** Initialize your data structure here. */ + + /** + * Initialize your data structure here. + */ private MyQueue() { stack = new Stack<>(); baseStack = new Stack<>(); } - /** Push element x to the back of queue. */ + /** + * Push element x to the back of queue. + */ private void push(int x) { System.out.println(stack.toString()); while (!stack.empty()) { @@ -24,19 +29,25 @@ private void push(int x) { } - /** Removes the element from in front of queue and returns that element. */ + /** + * Removes the element from in front of queue and returns that element. + */ private int pop() { Integer num = stack.pop(); return null == num ? -1 : num; } - /** Get the front element. */ + /** + * Get the front element. + */ private int peek() { Integer num = stack.peek(); return null == num ? -1 : num; } - /** Returns whether the queue is empty. */ + /** + * Returns whether the queue is empty. + */ private boolean empty() { return stack.empty() && baseStack.empty(); } diff --git a/java/src/juejin/lc/leetCode/MyStack.java b/java/src/juejin/lc/leetCode/MyStack.java index 073250b..4bb4487 100644 --- a/java/src/juejin/lc/leetCode/MyStack.java +++ b/java/src/juejin/lc/leetCode/MyStack.java @@ -14,12 +14,17 @@ public class MyStack { private Queue queue; - /** Initialize your data structure here. */ + + /** + * Initialize your data structure here. + */ private MyStack() { queue = new LinkedList<>(); } - /** Push element x onto stack. */ + /** + * Push element x onto stack. + */ private void push(int x) { queue.add(x); int size = queue.size(); @@ -29,19 +34,25 @@ private void push(int x) { } } - /** Removes the element on top of the stack and returns that element. */ + /** + * Removes the element on top of the stack and returns that element. + */ private int pop() { - Integer num = queue.poll(); - return null == num ? -1 : num; + Integer num = queue.poll(); + return null == num ? -1 : num; } - /** Get the top element. */ + /** + * Get the top element. + */ private int top() { - Integer num = queue.peek(); - return null == num ? -1 : num; + Integer num = queue.peek(); + return null == num ? -1 : num; } - /** Returns whether the stack is empty. */ + /** + * Returns whether the stack is empty. + */ private boolean empty() { return queue.isEmpty(); } diff --git a/java/src/juejin/lc/leetCode/NarcissisticNumber.java b/java/src/juejin/lc/leetCode/NarcissisticNumber.java index 87580e5..64fa485 100644 --- a/java/src/juejin/lc/leetCode/NarcissisticNumber.java +++ b/java/src/juejin/lc/leetCode/NarcissisticNumber.java @@ -5,17 +5,18 @@ * 求1000以内的水仙花数 * 153,370,371,407 * 153 = 1*1*1 + 5*5*5 + 3 * 3 * 3; + * * @author liuchao * @date 2019/8/22 */ public class NarcissisticNumber { - private static void solution (){ + private static void solution() { // 首先一定是三位数 for (int i = 100; i < 1000; i++) { int unit = i % 10; int ten = (i / 10) % 10; int hundred = (i / 10 / 10) % 10; - if(i == (unit * unit * unit + ten * ten * ten + hundred * hundred * hundred)){ + if (i == (unit * unit * unit + ten * ten * ten + hundred * hundred * hundred)) { System.out.println(i + " "); } } diff --git a/java/src/juejin/lc/leetCode/NumberOfBoomerangs.java b/java/src/juejin/lc/leetCode/NumberOfBoomerangs.java new file mode 100644 index 0000000..31f44e8 --- /dev/null +++ b/java/src/juejin/lc/leetCode/NumberOfBoomerangs.java @@ -0,0 +1,32 @@ +package juejin.lc.leetCode; + +/** + * @author + * @date 2020/10/15 + */ +public class NumberOfBoomerangs { + /** + * 给定平面上n 对不同的点,“回旋镖” 是由点表示的元组(i, j, k), + * 其中i和j之间的距离和i和k之间的距离相等(需要考虑元组的顺序)。 + *

+ * 找到所有回旋镖的数量。你可以假设n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中。 + *

+ * 示例: + *

+ * 输入: + * [[0,0],[1,0],[2,0]] + *

+ * 输出: + * 2 + *

+ * 解释: + * 两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]] + *

+ * + * @param points + * @return + */ + public int solution(int[][] points) { + return -1; + } +} diff --git a/java/src/juejin/lc/leetCode/NumberReverse.java b/java/src/juejin/lc/leetCode/NumberReverse.java index d159a2a..e543942 100644 --- a/java/src/juejin/lc/leetCode/NumberReverse.java +++ b/java/src/juejin/lc/leetCode/NumberReverse.java @@ -51,6 +51,7 @@ private static boolean isPalindrome(int x) { /** * 判断链表是否回文 * 快慢指针法 + * * @param head 链表 * @return 返回值 */ @@ -60,21 +61,21 @@ private boolean isPalindrome(ListNode head) { } ListNode slow = head; ListNode fast = head; - while (null != fast.next && null != fast.next.next){ + while (null != fast.next && null != fast.next.next) { slow = slow.next; fast = fast.next.next; } slow = slow.next; ListNode prev = null; - while (null != slow){ + while (null != slow) { ListNode next = slow.next; slow.next = prev; prev = slow; slow = next; } - while (null != prev){ - if (head.val != prev.val){ - return false; + while (null != prev) { + if (head.val != prev.val) { + return false; } head = head.next; prev = prev.next; @@ -85,6 +86,7 @@ private boolean isPalindrome(ListNode head) { private class ListNode { int val; ListNode next; + ListNode(int x) { val = x; } diff --git a/java/src/juejin/lc/leetCode/PlusOne.java b/java/src/juejin/lc/leetCode/PlusOne.java index 4adae03..2e2fda0 100644 --- a/java/src/juejin/lc/leetCode/PlusOne.java +++ b/java/src/juejin/lc/leetCode/PlusOne.java @@ -37,7 +37,7 @@ private int[] solution(int[] digits) { for (int i = 0; i < digits.length; i++) { newDigits[i + 1] = digits[i]; } - }else{ + } else { newDigits = digits; } return newDigits; @@ -45,7 +45,7 @@ private int[] solution(int[] digits) { public static void main(String[] args) { - int[] digits = {8,9,9}; + int[] digits = {8, 9, 9}; int[] res = new PlusOne().solution(digits); for (int i = 0; i < res.length; i++) { System.out.print(res[i] + " "); diff --git a/java/src/juejin/lc/leetCode/RemoveDuplicates.java b/java/src/juejin/lc/leetCode/RemoveDuplicates.java index 4129237..03a57f8 100644 --- a/java/src/juejin/lc/leetCode/RemoveDuplicates.java +++ b/java/src/juejin/lc/leetCode/RemoveDuplicates.java @@ -17,7 +17,7 @@ public class RemoveDuplicates { public int solution(int[] nums) { int index = 0; for (int i = 1; i < nums.length; i++) { - if (nums[i] == nums[i - 1]){ + if (nums[i] == nums[i - 1]) { ++index; continue; } @@ -29,7 +29,7 @@ public int solution(int[] nums) { } public static void main(String[] args) { - int[] nums = {1,1,2}; + int[] nums = {1, 1, 2}; RemoveDuplicates removeDuplicates = new RemoveDuplicates(); int length = removeDuplicates.solution(nums); System.out.println("length = " + length); diff --git a/java/src/juejin/lc/leetCode/RemoveElement.java b/java/src/juejin/lc/leetCode/RemoveElement.java index fb68297..2135420 100644 --- a/java/src/juejin/lc/leetCode/RemoveElement.java +++ b/java/src/juejin/lc/leetCode/RemoveElement.java @@ -4,6 +4,7 @@ * 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 * 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 + * * @author liuchao * @date 2019/5/24 */ @@ -11,18 +12,19 @@ public class RemoveElement { /** * 给定 nums = [3,2,2,3], val = 3, * 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 + * * @param nums * @param val * @return */ - public int solution(int[]nums, int val){ + public int solution(int[] nums, int val) { int index = 0; for (int i = 0; i < nums.length; i++) { - if (nums[i] == val){ + if (nums[i] == val) { ++index; continue; } - if (index > 0){ + if (index > 0) { nums[i - index] = nums[i]; } } @@ -31,9 +33,9 @@ public int solution(int[]nums, int val){ public static void main(String[] args) { RemoveElement removeElement = new RemoveElement(); - int[] nums = {3,2,2,3}; + int[] nums = {3, 2, 2, 3}; int val = 3; - int res = removeElement.solution(nums,val); + int res = removeElement.solution(nums, val); System.out.println(res); } } diff --git a/java/src/juejin/lc/leetCode/RemoveElements.java b/java/src/juejin/lc/leetCode/RemoveElements.java index 8b1bd48..b1dd9c5 100644 --- a/java/src/juejin/lc/leetCode/RemoveElements.java +++ b/java/src/juejin/lc/leetCode/RemoveElements.java @@ -3,65 +3,73 @@ public class RemoveElements { /** * 删除链表中等于给定值 val 的所有节点。 + *

+ * 示例: + *

+ * 输入: 1->2->6->3->4->5->6, val = 6 + * 输出: 1->2->3->4->5 * - * 示例: - * - * 输入: 1->2->6->3->4->5->6, val = 6 - * 输出: 1->2->3->4->5 * @param head 单链表 - * @param val 给定值 + * @param val 给定值 * @return 输出链表 */ private ListNode solution(ListNode head, int val) { //删除头结点时另做考虑(由于头结点没有前一个结点) - while (null != head && head.val == val){ + while (null != head && head.val == val) { head = head.next; } - if (null == head){ + if (null == head) { return null; } - ListNode node =head; + ListNode node = head; while (null != node.next) { - if (node.next.val == val){ + if (node.next.val == val) { node.next = node.next.next; - }else { + } else { node = node.next; } } return head; } - private ListNode solution2(ListNode head, int val){ + + private ListNode solution2(ListNode head, int val) { //创建一个虚拟头结点 //随机传任意一个不等于val的值作为虚拟头结点 ListNode dummyNode = new ListNode(val - 1); dummyNode.next = head; ListNode node = dummyNode; - while (null != node.next){ - if (node.next.val == val){ + while (null != node.next) { + if (node.next.val == val) { node.next = node.next.next; - }else { + } else { node = node.next; } } return dummyNode.next; } - private ListNode solution3(ListNode head, int val){ + + private ListNode solution3(ListNode head, int val) { // 递归 - if (null == head){ + if (null == head) { return null; } - head.next = solution3(head.next,val); - if (head.val == val){ + head.next = solution3(head.next, val); + if (head.val == val) { return head.next; } return head; } + private static class ListNode { int val; ListNode next; - ListNode(int x) { val = x; } + + ListNode(int x) { + val = x; + } } - private ListNode createNode(){ + + private ListNode createNode() { ListNode node1 = new ListNode(1); ListNode node2 = new ListNode(2); ListNode node3 = new ListNode(6); @@ -77,25 +85,27 @@ private ListNode createNode(){ node6.next = node7; return node1; } + private void print(ListNode listNode) { - while (null != listNode){ + while (null != listNode) { int val = listNode.val; System.out.print(val); - if (null != listNode.next){ + if (null != listNode.next) { System.out.print("->"); } listNode = listNode.next; } System.out.println(); } + public static void main(String[] args) { RemoveElements removeElements = new RemoveElements(); ListNode head = removeElements.createNode(); removeElements.print(head); int val = 6; - ListNode result = removeElements.solution(head,val); - ListNode result2 = removeElements.solution2(head,val); - ListNode result3 = removeElements.solution3(head,val); + ListNode result = removeElements.solution(head, val); + ListNode result2 = removeElements.solution2(head, val); + ListNode result3 = removeElements.solution3(head, val); removeElements.print(result); removeElements.print(result2); removeElements.print(result3); diff --git a/java/src/juejin/lc/leetCode/ReverseList.java b/java/src/juejin/lc/leetCode/ReverseList.java index 4f0a61a..d433784 100644 --- a/java/src/juejin/lc/leetCode/ReverseList.java +++ b/java/src/juejin/lc/leetCode/ReverseList.java @@ -5,26 +5,31 @@ */ public class ReverseList { private ListNode solution(ListNode head) { - ListNode resNode = null; - ListNode prevNode = null; - ListNode curNode = head; - while (null != curNode){ - ListNode nextNode = curNode.next; - if (null == nextNode) { - resNode = curNode; - } - curNode.next = prevNode; - prevNode = curNode; - curNode = nextNode; - } - return resNode; + ListNode resNode = null; + ListNode prevNode = null; + ListNode curNode = head; + while (null != curNode) { + ListNode nextNode = curNode.next; + if (null == nextNode) { + resNode = curNode; + } + curNode.next = prevNode; + prevNode = curNode; + curNode = nextNode; + } + return resNode; } + private static class ListNode { int val; ListNode next; - ListNode(int x) { val = x; } + + ListNode(int x) { + val = x; + } } - private ListNode createNode(){ + + private ListNode createNode() { ListNode node1 = new ListNode(1); ListNode node2 = new ListNode(2); ListNode node3 = new ListNode(3); @@ -36,17 +41,19 @@ private ListNode createNode(){ node4.next = node5; return node1; } + private void print(ListNode listNode) { - while (null != listNode){ + while (null != listNode) { int val = listNode.val; System.out.print(val); - if (null != listNode.next){ + if (null != listNode.next) { System.out.print("->"); } listNode = listNode.next; } System.out.println(); } + public static void main(String[] args) { ReverseList reverseList = new ReverseList(); ListNode head = reverseList.createNode(); diff --git a/java/src/juejin/lc/leetCode/SearchInsert.java b/java/src/juejin/lc/leetCode/SearchInsert.java index c37d2f8..7028b0e 100644 --- a/java/src/juejin/lc/leetCode/SearchInsert.java +++ b/java/src/juejin/lc/leetCode/SearchInsert.java @@ -27,7 +27,7 @@ public int solution(int[] nums, int target) { return i; } } - if (prev != -1){ + if (prev != -1) { return nums.length; } return -1; @@ -36,13 +36,13 @@ public int solution(int[] nums, int target) { public static void main(String[] args) { SearchInsert searchInsert = new SearchInsert(); // [1,3,5,6], 5 2 - int[] nums = {1,3,5,6}; - System.out.println(searchInsert.solution(nums,5)); + int[] nums = {1, 3, 5, 6}; + System.out.println(searchInsert.solution(nums, 5)); // [1,3,5,6], 2 1 - System.out.println(searchInsert.solution(nums,2)); + System.out.println(searchInsert.solution(nums, 2)); // [1,3,5,6], 7 4 - System.out.println(searchInsert.solution(nums,7)); + System.out.println(searchInsert.solution(nums, 7)); // [1,3,5,6], 0 0 - System.out.println(searchInsert.solution(nums,0)); + System.out.println(searchInsert.solution(nums, 0)); } } diff --git a/java/src/juejin/lc/leetCode/SortedArrayToBST.java b/java/src/juejin/lc/leetCode/SortedArrayToBST.java index 728a622..f399943 100644 --- a/java/src/juejin/lc/leetCode/SortedArrayToBST.java +++ b/java/src/juejin/lc/leetCode/SortedArrayToBST.java @@ -47,14 +47,16 @@ private static class TreeNode { val = x; } } - private void inOrderTraversal(TreeNode node){ - if (null == node){ + + private void inOrderTraversal(TreeNode node) { + if (null == node) { return; } System.out.print(node.val + " "); inOrderTraversal(node.left); inOrderTraversal(node.right); } + public static void main(String[] args) { SortedArrayToBST sortedArrayToBST = new SortedArrayToBST(); int[] nums = {-10, -3, 0, 5, 9}; diff --git a/java/src/juejin/lc/leetCode/StrStrSolution.java b/java/src/juejin/lc/leetCode/StrStrSolution.java index 4df25b3..627c2cc 100644 --- a/java/src/juejin/lc/leetCode/StrStrSolution.java +++ b/java/src/juejin/lc/leetCode/StrStrSolution.java @@ -7,12 +7,13 @@ * "" "" 0 * "**" "" 0 * "" "**" -1 + * * @author liuchao * @date 2019/5/24 */ public class StrStrSolution { public int solution(String haystack, String needle) { - if ("".equals(needle) ||needle.equals(haystack)) { + if ("".equals(needle) || needle.equals(haystack)) { return 0; } if ("".equals(haystack)) { @@ -40,6 +41,6 @@ public static void main(String[] args) { StrStrSolution strStrSolution = new StrStrSolution(); String hasystack = "a"; String needle = "a"; - System.out.println(strStrSolution.solution(hasystack,needle)); + System.out.println(strStrSolution.solution(hasystack, needle)); } } diff --git a/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java b/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java index c2169d8..b2c5cfa 100644 --- a/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java +++ b/java/src/juejin/lc/leetCode/SumOfLeftLeaves.java @@ -3,15 +3,15 @@ public class SumOfLeftLeaves { /** * 计算给定二叉树的所有左叶子之和。 - * + *

* 示例: - * - * 3 - * / \ - * 9 20 - * / \ - * 15 7 - * + *

+ * 3 + * / \ + * 9 20 + * / \ + * 15 7 + *

* 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 * * @param root @@ -26,14 +26,13 @@ public int solution(TreeNode root) { } /** - * * @param root 二叉树 * @param flag 是否是左节点 * @return */ private int recursion(TreeNode root, boolean flag) { // 边界条件 - if(null == root) { + if (null == root) { return 0; } if (flag && null == root.left && null == root.right) { diff --git a/java/src/juejin/lc/leetCode/ToHex.java b/java/src/juejin/lc/leetCode/ToHex.java index 0e48d7f..abe3855 100644 --- a/java/src/juejin/lc/leetCode/ToHex.java +++ b/java/src/juejin/lc/leetCode/ToHex.java @@ -10,19 +10,20 @@ public class ToHex { * 给定的数确保在32位有符号整数范围内。 * 不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。 * 示例 1: - * + *

* 输入: * 26 - * + *

* 输出: * "1a" * 示例 2: - * + *

* 输入: * -1 - * + *

* 输出: * "ffffffff" + * * @param num * @return */ diff --git a/java/src/juejin/lc/leetCode/TwoNum.java b/java/src/juejin/lc/leetCode/TwoNum.java index 9871507..fc552c1 100644 --- a/java/src/juejin/lc/leetCode/TwoNum.java +++ b/java/src/juejin/lc/leetCode/TwoNum.java @@ -5,37 +5,36 @@ /** * 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为gai目标值的 两个 整数。 - * + *

* 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 - * + *

* 示例: - * + *

* 给定 nums = [2, 7, 11, 15], target = 9 - * + *

* 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] - * - * @author liuchao * + * @author liuchao */ public class TwoNum { - public static int[] twoNumSum(int[] nums, int target) { - Map map = new HashMap(); - for (int i = 0; i < nums.length; i++) { - int complement = target - nums[i]; - if (map.containsKey(complement)) { - return new int[] { map.get(complement), i }; - } - map.put(nums[i], i); - } - throw new IllegalArgumentException("No two sum solution"); - } + public static int[] twoNumSum(int[] nums, int target) { + Map map = new HashMap(); + for (int i = 0; i < nums.length; i++) { + int complement = target - nums[i]; + if (map.containsKey(complement)) { + return new int[]{map.get(complement), i}; + } + map.put(nums[i], i); + } + throw new IllegalArgumentException("No two sum solution"); + } - public static void main(String[] args) { - int[] num = new int[] { 2, 7, 11, 15 }; - int target = 9; - int[] res = twoNumSum(num, target); - for (int i = 0; i < res.length; i++) { - System.out.print(res[i] + " "); - } - } + public static void main(String[] args) { + int[] num = new int[]{2, 7, 11, 15}; + int target = 9; + int[] res = twoNumSum(num, target); + for (int i = 0; i < res.length; i++) { + System.out.print(res[i] + " "); + } + } } diff --git a/java/src/juejin/lc/leetCode/TwoSum.java b/java/src/juejin/lc/leetCode/TwoSum.java index 564e766..1d89254 100644 --- a/java/src/juejin/lc/leetCode/TwoSum.java +++ b/java/src/juejin/lc/leetCode/TwoSum.java @@ -1,6 +1,7 @@ package juejin.lc.leetCode; -import java.util.*; +import java.util.HashMap; +import java.util.Map; /** * 两数之和 @@ -44,11 +45,24 @@ public int[] solution(int[] numbers, int target) { return result; } + public int[] solution2(int[] numbers, int target) { + Map map = new HashMap<>(); + for (int i = 0; i < numbers.length; ++i) { + if (map.containsKey(target - numbers[i])) { + return new int[]{map.get(target - numbers[i]), i}; + } + map.put(numbers[i], i); + } + return new int[0]; + } + public static void main(String[] args) { TwoSum twoSum = new TwoSum(); - int[] numbers = {12, 13, 23, 28, 43, 44, 59, 60, 61, 68, 70, 86, 88, 92, 124, 125, 136, 168, 173, 173, 180, 199, 212, 221, 227, 230, 277, 282, 306, 314, 316, 321, 325, 328, 336, 337, 363, 365, 368, 370, 370, 371, 375, 384, 387, 394, 400, 404, 414, 422, 422, 427, 430, 435, 457, 493, 506, 527, 531, 538, 541, 546, 568, 583, 585, 587, 650, 652, 677, 691, 730, 737, 740, 751, 755, 764, 778, 783, 785, 789, 794, 803, 809, 815, 847, 858, 863, 863, 874, 887, 896, 916, 920, 926, 927, 930, 933, 957, 981, 997}; - int target = 542; - int[] result = twoSum.solution(numbers, target); + int[] numbers = {2, 7, 11, 15}; +// int[] numbers = {12, 13, 23, 28, 43, 44, 59, 60, 61, 68, 70, 86, 88, 92, 124, 125, 136, 168, 173, 173, 180, 199, 212, 221, 227, 230, 277, 282, 306, 314, 316, 321, 325, 328, 336, 337, 363, 365, 368, 370, 370, 371, 375, 384, 387, 394, 400, 404, 414, 422, 422, 427, 430, 435, 457, 493, 506, 527, 531, 538, 541, 546, 568, 583, 585, 587, 650, 652, 677, 691, 730, 737, 740, 751, 755, 764, 778, 783, 785, 789, 794, 803, 809, 815, 847, 858, 863, 863, 874, 887, 896, 916, 920, 926, 927, 930, 933, 957, 981, 997}; + int target = 9; +// int target = 542; + int[] result = twoSum.solution2(numbers, target); for (int i = 0; i < result.length; i++) { System.out.print(result[i] + " "); } diff --git a/java/src/juejin/lc/other/IdWorker.java b/java/src/juejin/lc/other/IdWorker.java index c60985a..bb899c9 100644 --- a/java/src/juejin/lc/other/IdWorker.java +++ b/java/src/juejin/lc/other/IdWorker.java @@ -48,6 +48,7 @@ public IdWorker(long workerId, long datacenterId, long sequence) { this.datacenterId = datacenterId; this.sequence = sequence; } + public long getWorkerId() { return workerId; } diff --git a/java/src/juejin/lc/sorts/BaseSort.java b/java/src/juejin/lc/sorts/BaseSort.java index 8687628..4f63904 100644 --- a/java/src/juejin/lc/sorts/BaseSort.java +++ b/java/src/juejin/lc/sorts/BaseSort.java @@ -95,6 +95,7 @@ private void quickSort(int[] arrays, int head, int tail) { quickSort(arrays, head, pivot - 1); quickSort(arrays, pivot + 1, tail); } + /** * 分区函数 * @@ -108,7 +109,7 @@ private int partition(int[] arrays, int head, int tail) { int i = head; for (int j = head; j < tail; ++j) { if (arrays[j] < pivot) { - if(i == j) { + if (i == j) { ++i; } else { int tmp = arrays[i]; diff --git a/java/src/juejin/lc/sql/MergeTwoTable.sql b/java/src/juejin/lc/sql/MergeTwoTable.sql index 5c276a0..155fe89 100644 --- a/java/src/juejin/lc/sql/MergeTwoTable.sql +++ b/java/src/juejin/lc/sql/MergeTwoTable.sql @@ -1,6 +1,16 @@ -Create table Person (PersonId int, FirstName varchar(255), LastName varchar(255)) -Create table Address (AddressId int, PersonId int, City varchar(255), State varchar(255)) -Truncate table Person +Create table Person +( + PersonId int, + FirstName varchar(255), + LastName varchar(255) +) +Create table Address +( + AddressId int, + PersonId int, + City varchar(255), + State varchar(255) +) Truncate table Person insert into Person (PersonId, LastName, FirstName) values ('1', 'Wang', 'Allen') Truncate table Address insert into Address (AddressId, PersonId, City, State); @@ -26,4 +36,6 @@ insert into Address (AddressId, PersonId, City, State); -- AddressId 是上表主键 -- 编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息: -- FirstName, LastName, City, State -select p.FirstName, p.LastName, a.City, a.State from Person p left join Address a on p.PersonId = a.PersonId; \ No newline at end of file +select p.FirstName, p.LastName, a.City, a.State +from Person p + left join Address a on p.PersonId = a.PersonId; \ No newline at end of file diff --git a/java/src/juejin/lc/sql/TheSecondSalary.sql b/java/src/juejin/lc/sql/TheSecondSalary.sql index 3b26787..17db358 100644 --- a/java/src/juejin/lc/sql/TheSecondSalary.sql +++ b/java/src/juejin/lc/sql/TheSecondSalary.sql @@ -1,21 +1,50 @@ -Create table If Not Exists Employee (Id int, Salary int) -Truncate table Employee -insert into Employee (Id, Salary) values ('1', '100') -insert into Employee (Id, Salary) values ('2', '200') -insert into Employee (Id, Salary) values ('3', '300') - -编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。 -+----+--------+ -| Id | Salary | -+----+--------+ -| 1 | 100 | -| 2 | 200 | -| 3 | 300 | -+----+--------+ -例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。 -+---------------------+ -| SecondHighestSalary | -+---------------------+ -| 200 | -+---------------------+ - select (select distinct salary from Employee order by salary desc limit 1,1) as SecondHighestSalary ; \ No newline at end of file +Create table If Not Exists Employee +( + Id + int, + Salary + int +) + Truncate table Employee + insert into Employee +( + Id, + Salary +) values +( + '1', + '100' +) + insert into Employee +( + Id, + Salary +) values +( + '2', + '200' +) + insert into Employee +( + Id, + Salary +) values +( + '3', + '300' +) + 编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。 + +----+--------+ + | Id | Salary | + +----+--------+ + | 1 | 100 | + | 2 | 200 | + | 3 | 300 | + +----+--------+ + 例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。 + +---------------------+ + | SecondHighestSalary | + +---------------------+ + | 200 | + +---------------------+ +select (select distinct salary from Employee order by salary desc limit 1,1) as SecondHighestSalary; \ No newline at end of file diff --git a/java/src/juejin/lc/string/Pattern.java b/java/src/juejin/lc/string/Pattern.java index 8990397..3d62fe2 100644 --- a/java/src/juejin/lc/string/Pattern.java +++ b/java/src/juejin/lc/string/Pattern.java @@ -46,10 +46,10 @@ private boolean isMatch(String txt) { /** * 递归匹配 * - * @param ti 字符索引 - * @param pj 正则表达式索引 + * @param ti 字符索引 + * @param pj 正则表达式索引 * @param txtChars 字符 - * @param tlen 字符长度 + * @param tlen 字符长度 */ private void recursiveMatch(int ti, int pj, char[] txtChars, int tlen) { if (match) return; @@ -75,9 +75,9 @@ public static void main(String[] args) { Pattern pattern = new Pattern(patten); String txtT = "666@cc.com"; boolean resT = pattern.isMatch(txtT); - System.out.println(txtT + "的匹配结果:" + resT); + System.out.println(txtT + "的匹配结果:" + resT); String txtF = "666@c.con"; boolean resF = pattern.isMatch(txtF); - System.out.println(txtF + "的匹配结果:" + resF); + System.out.println(txtF + "的匹配结果:" + resF); } }