7 | * 示例 1:
8 | * 输入: num1 = "2", num2 = "3"
9 | * 输出: "6"
10 | *
11 | * 示例 2:
12 | * 输入: num1 = "123", num2 = "456"
13 | * 输出: "56088"
14 | *
15 | * 说明:
16 | * num1 和 num2 的长度小于110。
17 | * num1 和 num2 只包含数字 0-9。
18 | * num1 和 num2 均不以零开头,除非是数字 0 本身。
19 | * 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
20 | *
21 | * @author 刘壮飞
22 | * https://github.com/zfman.
23 | * https://blog.csdn.net/lzhuangfei.
24 | */
25 | public class Solution43 {
26 | public String multiply(String num1, String num2) {
27 | return null;
28 | }
29 |
30 | public static void main(String[] args) {
31 | String num1="123";
32 | String num2="456";
33 | String r=new Solution43().multiply(num1,num2);
34 | System.out.println(r);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution53.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | /**
4 | * 53.最大子序和.
5 | * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
6 | *
7 | * 示例:
8 | * 输入: [-2,1,-3,4,-1,2,1,-5,4],
9 | * 输出: 6
10 | * 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
11 | *
12 | * 进阶:
13 | *
14 | * 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
15 | *
16 | * @author 刘壮飞
17 | * https://github.com/zfman.
18 | * https://blog.csdn.net/lzhuangfei.
19 | */
20 | public class Solution53 {
21 | public int maxSubArray(int[] nums) {
22 | if (nums.length ==0) return 0;
23 | int sum = nums[0];
24 | int tmp=nums[0];
25 | for(int i=1;i0){
27 | tmp+=nums[i];
28 | if(tmp>sum) sum=tmp;
29 | }else{
30 | tmp=nums[i];
31 | if(tmp>sum) sum=tmp;
32 | }
33 | }
34 | return sum;
35 | }
36 |
37 | public static void main(String[] args) {
38 | int[] nums = {
39 | -2, 1, -3, 4, -1, 2, 1, -5, 4
40 | };
41 | int r = new Solution53().maxSubArray(nums);
42 | System.out.println(r);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution58.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | /**
4 | * 58. 最后一个单词的长度.
5 | * 给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。
6 | *
7 | * 如果不存在最后一个单词,请返回 0 。
8 | *
9 | * 说明:一个单词是指由字母组成,但不包含任何空格的字符串。
10 | *
11 | * 示例:
12 | * 输入: "Hello World"
13 | * 输出: 5
14 | *
15 | * @author 刘壮飞
16 | * https://github.com/zfman.
17 | * https://blog.csdn.net/lzhuangfei.
18 | */
19 | public class Solution58 {
20 |
21 | /**
22 | * 很简单,切分为数组,取最后一个元素即可
23 | * @param s
24 | * @return
25 | */
26 | public int lengthOfLastWord(String s) {
27 | if(s==null||s.length()==0) return 0;
28 | String[] a=s.trim().split(" +");
29 | if(a==null||a.length==0) return 0;
30 | return a[a.length-1].length();
31 | }
32 |
33 | public static void main(String[] args) {
34 | String s = "Hello World";
35 | int r = new Solution58().lengthOfLastWord(s);
36 | System.out.println(r);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution62.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | /**
4 | * 62. 不同路径
5 | *
6 | * 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
7 | *
8 | * 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
9 | *
10 | * 问总共有多少条不同的路径?
11 | *
12 | *
13 | * 例如,上图是一个7 x 3 的网格。有多少可能的路径?
14 | *
15 | * 说明:m 和 n 的值均不超过 100。
16 | *
17 | * 示例 1:
18 | *
19 | * 输入: m = 3, n = 2
20 | * 输出: 3
21 | * 解释:
22 | * 从左上角开始,总共有 3 条路径可以到达右下角。
23 | * 1. 向右 -> 向右 -> 向下
24 | * 2. 向右 -> 向下 -> 向右
25 | * 3. 向下 -> 向右 -> 向右
26 | *
27 | * 示例 2:
28 | *
29 | * 输入: m = 7, n = 3
30 | * 输出: 28
31 | *
32 | * @author 刘壮飞
33 | * https://github.com/zfman.
34 | * https://blog.csdn.net/lzhuangfei.
35 | */
36 | public class Solution62 {
37 |
38 | /**
39 | * 使用动态规划求解.
40 | *
41 | * 第一行、第一列设为1,从第二行第二列开始,
42 | * 该位置的路径数等于左侧的路径数+上侧的路径数,
43 | * 机器人到达右下角的路径未arr[m-1][n-1]
44 | *
45 | * @param m
46 | * @param n
47 | * @return
48 | */
49 | public int uniquePaths(int m, int n) {
50 | int[][] arr=new int[m][n];
51 | for(int i=0;i 向右 -> 向下 -> 向下
31 | * 2. 向下 -> 向下 -> 向右 -> 向右
32 | *
33 | * @author 刘壮飞
34 | * https://github.com/zfman.
35 | * https://blog.csdn.net/lzhuangfei.
36 | */
37 | public class Solution63 {
38 | /**
39 | * 本题目增加了障碍物,所以在初始化时需要注意
40 | *
41 | * 初始化时将第一行、第一列障碍物位置以及其之后的位置初始化为0,其他位置为1
42 | * 计算时,如果该位置为障碍物,置0,否则置为上策和左侧的和
43 | *
44 | * @param obstacleGrid
45 | * @return
46 | */
47 | public int uniquePathsWithObstacles(int[][] obstacleGrid) {
48 | if(obstacleGrid.length<1) return 0;
49 | int m=obstacleGrid.length;
50 | int n=obstacleGrid[0].length;
51 | int[][] count=new int[m][n];
52 |
53 | //初始化
54 | boolean cannotContinue1=false;
55 | boolean cannotContinue2=false;
56 | for(int i=0;i=0;i--){
38 | if(digits[i]<9){
39 | digits[i]+=1;
40 | break;
41 | }else {
42 | digits[i]=0;
43 | }
44 | }
45 | if(i<0){
46 | int[] r=new int[digits.length+1];
47 | r[0]=1;
48 | for(int m=1;m= 0; i--) {
47 | char ch1 = a.charAt(i);
48 | char ch2 = b.charAt(i);
49 | int k=ch1-'0'+(ch2-'0');
50 | if(plusOne) k=k+1;
51 | if (k>1) {
52 | k=k-2;
53 | r = k+ r;
54 | plusOne=true;
55 | } else {
56 | r=k+r;
57 | plusOne=false;
58 | }
59 | }
60 | if(i<0&&plusOne){
61 | r="1"+r;
62 | }
63 | return r;
64 | }
65 |
66 | public static void main(String[] args) {
67 | String a = "1010";
68 | String b = "1011";
69 | String r = new Solution67().addBinary(a, b);
70 | System.out.println(r);//10101
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution69.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | /**
4 | * 69. x 的平方根
5 | * 实现 int sqrt(int x) 函数。
6 | *
7 | * 计算并返回 x 的平方根,其中 x 是非负整数。
8 | *
9 | * 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
10 | *
11 | * 示例 1:
12 | * 输入: 4
13 | * 输出: 2
14 | *
15 | * 示例 2:
16 | * 输入: 8
17 | * 输出: 2
18 | * 说明: 8 的平方根是 2.82842...,
19 | * 由于返回类型是整数,小数部分将被舍去。
20 | *
21 | * @author 刘壮飞
22 | * https://github.com/zfman.
23 | * https://blog.csdn.net/lzhuangfei.
24 | */
25 | public class Solution69 {
26 |
27 | /**
28 | * 调用系统库
29 | * @param x
30 | * @return
31 | */
32 | public int mySqrt(int x) {
33 | return (int)Math.sqrt(x);
34 | }
35 |
36 | /**
37 | * 这个方法我还不太理解,备注
38 | * @param x
39 | * @return
40 | */
41 | public int mySqrt2(int x) {
42 | if(x<=1) return x;
43 | long m=x;
44 | while(m>x/m){
45 | m=(m+x/m)/2;
46 | }
47 | return (int)m;
48 | }
49 |
50 | public static void main(String[] args) {
51 | int x = 8;
52 | int r = new Solution69().mySqrt(x);
53 | int r2=new Solution69().mySqrt2(x);
54 | System.out.println("Method1:"+r);
55 | System.out.println("Method2:"+r2);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution7.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | /**
4 | * 反转整数.
5 | * 给定一个 32 位有符号整数,将整数中的数字进行反转。
6 | *
7 | * 示例 1:
8 | * 输入: 123
9 | * 输出: 321
10 | *
11 | * 示例 2:
12 | * 输入: -123
13 | * 输出: -321
14 | *
15 | * 示例 3:
16 | * 输入: 120
17 | * 输出: 21
18 | *
19 | * 注意:
20 | * 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。根据这个假设,如果反转后的整数溢出,则返回 0。
21 | *
22 | * @author 刘壮飞
23 | * https://github.com/zfman.
24 | * https://blog.csdn.net/lzhuangfei.
25 | */
26 | public class Solution7 {
27 |
28 | /**
29 | * 用long保存结果.从低位开始计算,注意负数的处理
30 | * @param x
31 | * @return
32 | */
33 | public int reverse(int x) {
34 | int head=1;
35 | if(x<0) {
36 | x=-x;
37 | head=-1;
38 | }
39 |
40 | int t=x%10;
41 | long r=0;
42 | x=x/10;
43 | while(x!=0){
44 | r=(r+t)*10;
45 | t=x%10;
46 | x=x/10;
47 | }
48 | r=(r+t);
49 |
50 | if((head*r>(Math.pow(2,31)-1))||(head*r<-1*(Math.pow(2,31)-1))) return 0;
51 | return (int)(head*r);
52 | }
53 |
54 | public static void main(String[] args){
55 | int x=-123;
56 | int r=new Solution7().reverse(x);
57 | System.out.println(r);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution8.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | /**
4 | * 未完成
5 | * @author 刘壮飞
6 | * https://github.com/zfman.
7 | * https://blog.csdn.net/lzhuangfei.
8 | */
9 | public class Solution8 {
10 |
11 | public int myAtoi(String str) {
12 | return 0;
13 | }
14 |
15 | public static void main(String[] args){
16 | String str="+-2";
17 | int r=new Solution8().myAtoi(str);
18 | System.out.println(r);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution83.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | import leetcode.common.LinkedUtils;
4 | import leetcode.common.ListNode;
5 |
6 | /**
7 | * 83. 删除排序链表中的重复元素.
8 | * 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
9 | *
10 | * 示例 1:
11 | * 输入: 1->1->2
12 | * 输出: 1->2
13 | *
14 | * 示例 2:
15 | * 输入: 1->1->2->3->3
16 | * 输出: 1->2->3
17 | *
18 | * @author 刘壮飞
19 | * https://github.com/zfman.
20 | * https://blog.csdn.net/lzhuangfei.
21 | */
22 | public class Solution83 {
23 | /**
24 | * 从第二个元素开始,和它之前的元素比较,
25 | * 如果相同,删除当前节点,继续比较直至末尾
26 | * @param head
27 | * @return
28 | */
29 | public ListNode deleteDuplicates(ListNode head) {
30 | ListNode p=head,q=null;
31 | while(p!=null){
32 | if(q!=null&&p.val==q.val) {
33 | q.next=p.next;
34 | p=q.next;
35 | }else{
36 | q=p;
37 | p=p.next;
38 | }
39 | }
40 |
41 | return head;
42 | }
43 |
44 | public static void main(String[] args) {
45 | int[] array={
46 | 1,1,2,2,2,2,2
47 | };
48 | ListNode head=LinkedUtils.arrayToLinkedList(array);
49 | ListNode r=new Solution83().deleteDuplicates(head);
50 | LinkedUtils.print(r);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution9.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | /**
4 | * 回文数.
5 | * 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
6 | *
7 | * 示例 1:
8 | * 输入: 121
9 | * 输出: true
10 | *
11 | * 示例 2:
12 | * 输入: -121
13 | * 输出: false
14 | * 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
15 | *
16 | * 示例 3:
17 | * 输入: 10
18 | * 输出: false
19 | * 解释: 从右向左读, 为 01 。因此它不是一个回文数。
20 | *
21 | * 进阶:
22 | *
23 | * 你能不将整数转为字符串来解决这个问题吗?
24 | *
25 | * @author 刘壮飞
26 | * https://github.com/zfman.
27 | * https://blog.csdn.net/lzhuangfei.
28 | */
29 | public class Solution9 {
30 |
31 | /**
32 | * 反转所有的数字,比较和原值是否相同.
33 | *
34 | * @param x
35 | * @return
36 | */
37 | public boolean isPalindrome(int x) {
38 | int t=x;
39 | if(x<0) return false;
40 | if(x<10) return true;
41 | long m=0;
42 | while(x!=0){
43 | m=(m+x%10)*10;
44 | x=x/10;
45 | }
46 |
47 | m=m/10;
48 | if(m==t) return true;
49 | return false;
50 | }
51 |
52 | /**
53 | * 反转一半的数字.
54 | * 详见题目解析>
55 | *
56 | * 首先,我们应该处理一些临界情况。所有负数都不可能是回文,
57 | * 例如:-123 不是回文,因为 - 不等于 3。所以我们可以对所有负数返回 false。
58 | *
59 | * 现在,让我们来考虑如何反转后半部分的数字。
60 | * 对于数字 1221,如果执行 1221 % 10,我们将得到最后一位数字 1,要得到倒数第二位数字,
61 | * 我们可以先通过除以 10 把最后一位数字从 1221 中移除,1221 / 10 = 122,再求出上一步结果除以10的余数,
62 | * 122 % 10 = 2,就可以得到倒数第二位数字。如果我们把最后一位数字乘以10,再加上倒数第二位数字,
63 | * 1 * 10 + 2 = 12,就得到了我们想要的反转后的数字。 如果继续这个过程,我们将得到更多位数的反转数字。
64 | *
65 | * 现在的问题是,我们如何知道反转数字的位数已经达到原始数字位数的一半?
66 | *
67 | * 我们将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于反转后的数字时,就意味着我们已经处理了一半位数的数字。
68 | *
69 | * @param x
70 | * @return
71 | */
72 | public boolean isPalindrome2(int x) {
73 | // 特殊情况:
74 | // 如上所述,当 x < 0 时,x 不是回文数。
75 | // 同样地,如果数字的最后一位是 0,为了使该数字为回文,
76 | // 则其第一位数字也应该是 0
77 | // 只有 0 满足这一属性
78 | if(x<0||(x%10==0&&x!=0)) return false;
79 |
80 | int revertedNumber=0;
81 | while(x>revertedNumber){
82 | revertedNumber=revertedNumber*10+x%10;
83 | x/=10;
84 | }
85 |
86 | // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
87 | // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
88 | // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
89 | return x==revertedNumber||x==revertedNumber/10;
90 | }
91 |
92 | public static void main(String[] args) {
93 | int x=1000000001;
94 | boolean b = new Solution9().isPalindrome(x);
95 | boolean b2 = new Solution9().isPalindrome2(x);
96 | System.out.println("Method1:"+b);
97 | System.out.println("Method2:"+b2);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution1_100/Solution91.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution1_100;
2 |
3 | /**
4 | * 91. 解码方法
5 | *
6 | * 一条包含字母 A-Z 的消息通过以下方式进行了编码:
7 | *
8 | * 'A' -> 1
9 | * 'B' -> 2
10 | * ...
11 | * 'Z' -> 26
12 | * 给定一个只包含数字的非空字符串,请计算解码方法的总数。
13 | *
14 | * 示例 1:
15 | *
16 | * 输入: "12"
17 | * 输出: 2
18 | * 解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。
19 | * 示例 2:
20 | *
21 | * 输入: "226"
22 | * 输出: 3
23 | * 解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
24 | *
25 | * @author 刘壮飞
26 | * https://github.com/zfman.
27 | * https://blog.csdn.net/lzhuangfei.
28 | */
29 | public class Solution91 {
30 |
31 | /**
32 | * 1.长度小于1,返回0
33 | * 2.dp的长度比字符串长度多一个,第一位默认为1
34 | * 3.对s中的每个字符:
35 | * ch为'0',该位置为0,否则,为上一个值
36 | * 如果可以和上个元素组合为符合的数字,
37 | * 那么该位置等于该位置的值+上上个位置的值
38 | *
39 | * @param s
40 | * @return
41 | */
42 | public int numDecodings(String s) {
43 | if(s==null||s.length()<1) return 0;
44 | int[] dp=new int[s.length()+1];
45 | dp[0]=1;
46 | for(int i=1;i<=s.length();i++){
47 | dp[i]=s.charAt(i-1)=='0'?0:dp[i-1];
48 | if(i>1&&(s.charAt(i-2)=='1'||(s.charAt(i-2)=='2'&&s.charAt(i-1)<='6'))){
49 | dp[i]+=dp[i-2];
50 | }
51 | }
52 | return dp[s.length()];
53 | }
54 |
55 | public static void main(String[] args){
56 | String s="110";
57 | int r=new Solution91().numDecodings(s);
58 | System.out.println(r);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution201_300/Solution226.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution201_300;
2 |
3 | import leetcode.common.TreeNode;
4 | import leetcode.common.TreeUtils;
5 |
6 | /**
7 | * 226. 翻转二叉树
8 | *
9 | * 翻转一棵二叉树。
10 | *
11 | * 示例:
12 | *
13 | * 输入:
14 | *
15 | * 4
16 | * / \
17 | * 2 7
18 | * / \ / \
19 | * 1 3 6 9
20 | * 输出:
21 | *
22 | * 4
23 | * / \
24 | * 7 2
25 | * / \ / \
26 | * 9 6 3 1
27 | * 备注:
28 | * 这个问题是受到 Max Howell 的 原问题 启发的 :
29 | *
30 | * 谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。
31 | *
32 | * @author 刘壮飞
33 | * https://github.com/zfman.
34 | * https://blog.csdn.net/lzhuangfei.
35 | */
36 | public class Solution226 {
37 | public TreeNode invertTree(TreeNode root) {
38 | doThing(root);
39 | return root;
40 | }
41 |
42 | public void doThing(TreeNode root) {
43 | if(root!=null){
44 | doThing(root.left);
45 | doThing(root.right);
46 | TreeNode tmp=root.left;
47 | root.left=root.right;
48 | root.right=tmp;
49 | }
50 | }
51 |
52 | public static void main(String[] args){
53 | TreeNode root=TreeUtils.stringToTree("421##3##76##9##");
54 | TreeNode r=new Solution226().invertTree(root);
55 | TreeUtils.travser(r);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution201_300/Solution257.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution201_300;
2 |
3 | import leetcode.common.TreeNode;
4 | import leetcode.common.TreeUtils;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * 257. 二叉树的所有路径
11 | *
12 | * 给定一个二叉树,返回所有从根节点到叶子节点的路径。
13 | *
14 | * 说明: 叶子节点是指没有子节点的节点。
15 | *
16 | * 示例:
17 | *
18 | * 输入:
19 | *
20 | * 1
21 | * / \
22 | * 2 3
23 | * \
24 | * 5
25 | *
26 | * 输出: ["1->2->5", "1->3"]
27 | *
28 | * 解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
29 | *
30 | * @author 刘壮飞
31 | * https://github.com/zfman.
32 | * https://blog.csdn.net/lzhuangfei.
33 | */
34 | public class Solution257 {
35 | public List binaryTreePaths(TreeNode root) {
36 | List list=new ArrayList<>();
37 | todo(root,list,"");
38 | return list;
39 | }
40 |
41 | public void todo(TreeNode root,List list,String s) {
42 | String tmp=(s.length()==0?"":s+"->");
43 | if(root!=null){
44 | if(root.left==null&&root.right==null) {
45 | list.add(tmp+root.val);
46 | }else{
47 | todo(root.left,list,tmp+root.val);
48 | todo(root.right,list,tmp+root.val);
49 | }
50 | }
51 | }
52 |
53 | public static void main(String[] args){
54 | TreeNode root=TreeUtils.stringToTree("12#5##3##");
55 | List r=new Solution257().binaryTreePaths(root);
56 | for(String s:r){
57 | System.out.println(s);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution301_400/Solution303.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution301_400;
2 |
3 | /**
4 | * 303. 区域和检索 - 数组不可变
5 | *
6 | * 给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
7 | *
8 | * 示例:
9 | *
10 | * 给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange()
11 | *
12 | * sumRange(0, 2) -> 1
13 | * sumRange(2, 5) -> -1
14 | * sumRange(0, 5) -> -3
15 | * 说明:
16 | *
17 | * 你可以假设数组不可变。
18 | * 会多次调用 sumRange 方法。
19 | *
20 | * 两种方法
21 | *
22 | * @author 刘壮飞
23 | * https://github.com/zfman.
24 | * https://blog.csdn.net/lzhuangfei.
25 | */
26 | public class Solution303 {
27 | public static void main(String[] args) {
28 | int[] nums = {
29 | -2, 0, 3, -5, 2, -1
30 | };
31 | NumArray array = new NumArray(nums);
32 | int r1 = array.sumRange(0,2);
33 | int r2=array.sumRange(2,5);
34 | int r3=array.sumRange(0,5);
35 | System.out.println("Method1:"+r1+" "+r2+" "+r3);
36 |
37 | NumArray2 array2 = new NumArray2(nums);
38 | int m1 = array.sumRange(0,2);
39 | int m2=array.sumRange(2,5);
40 | int m3=array.sumRange(0,5);
41 | System.out.println("Method2:"+m1+" "+m2+" "+m3);
42 | }
43 | }
44 |
45 | /**
46 | * 第一种方法
47 | */
48 | class NumArray {
49 |
50 | int[] nums;
51 |
52 | public NumArray(int[] nums) {
53 | this.nums=nums;
54 | }
55 |
56 | public int sumRange(int i, int j) {
57 | if(i<0||j>=nums.length||i>j) return 0;
58 | int sum=0;
59 | for(;i<=j;i++){
60 | sum+=nums[i];
61 | }
62 | return sum;
63 | }
64 | }
65 |
66 | /**
67 | * 第二种方法,推荐
68 | *
69 | * 由于数组是不可变的,所以在构造函数初始化时将上一个元素与当前值的和给计算出来
70 | */
71 | class NumArray2 {
72 |
73 | int[] sum;
74 |
75 | public NumArray2(int[] nums) {
76 | sum=new int[nums.length+1];
77 | sum[0]=0;
78 | for(int i=1;i 8
22 | * sumRegion(1, 1, 2, 2) -> 11
23 | * sumRegion(1, 2, 2, 4) -> 12
24 | * 说明:
25 | *
26 | * 你可以假设矩阵不可变。
27 | * 会多次调用 sumRegion 方法。
28 | * 你可以假设 row1 ≤ row2 且 col1 ≤ col2。
29 | *
30 | * @author 刘壮飞
31 | * https://github.com/zfman.
32 | * https://blog.csdn.net/lzhuangfei.
33 | */
34 | public class Solution304 {
35 | public static void main(String[] args) {
36 | int[][] matrix = {
37 | {3, 0, 1, 4, 2},
38 | {5, 6, 3, 2, 1},
39 | {1, 2, 0, 1, 5},
40 | {4, 1, 0, 1, 7},
41 | {1, 0, 3, 0, 5}
42 | };
43 | NumMatrix numMatrix= new NumMatrix(matrix);
44 | int m1 = numMatrix.sumRegion(2, 1, 4, 3);
45 | int m2 = numMatrix.sumRegion(1, 1, 2, 2);
46 | int m3 = numMatrix.sumRegion(1, 2, 2, 4);
47 | System.out.println("Method2:" + m1 + " " + m2 + " " + m3);
48 | }
49 | }
50 |
51 | /**
52 | * 必须使用高效的算法,否则通不过的
53 | */
54 | class NumMatrix {
55 |
56 | //dp[i][j]:从(0,0)->(i,j)围成的矩形的和
57 | int[][] dp;
58 |
59 | public NumMatrix(int[][] matrix) {
60 | if(matrix.length<=0||matrix[0].length<=0){
61 | this.dp=null;
62 | return;
63 | }
64 | this.dp=new int[matrix.length][matrix[0].length];
65 |
66 | //初始化,按行累加
67 | for(int i=0;i(i,j)围成的矩形的和.
84 | * 取值的时候需要注意边界值
85 | *
86 | * @param row1 起始行
87 | * @param col1 起始列
88 | * @param row2 终止行
89 | * @param col2 中止列
90 | * @return
91 | */
92 | public int sumRegion(int row1, int col1, int row2, int col2) {
93 | if(dp==null) return 0;
94 | if(row1==0){
95 | if(col1==0){
96 | return dp[row2][col2];
97 | }
98 | return dp[row2][col2]-dp[row2][col1-1];
99 | }else{
100 | if(col1==0){
101 | return dp[row2][col2]-dp[row1-1][col2];
102 | }
103 | return dp[row2][col2]-dp[row1-1][col2]-dp[row2][col1-1]+dp[row1-1][col1-1];
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution301_400/Solution349.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution301_400;
2 |
3 | import utils.ArrayUtils;
4 |
5 | import java.util.Arrays;
6 | import java.util.HashMap;
7 | import java.util.HashSet;
8 | import java.util.Set;
9 |
10 | /**
11 | * 349. 两个数组的交集
12 | *
13 | * 给定两个数组,编写一个函数来计算它们的交集。
14 | *
15 | * 示例 1:
16 | *
17 | * 输入: nums1 = [1,2,2,1], nums2 = [2,2]
18 | * 输出: [2]
19 | * 示例 2:
20 | *
21 | * 输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
22 | * 输出: [9,4]
23 | * 说明:
24 | *
25 | * 输出结果中的每个元素一定是唯一的。
26 | * 我们可以不考虑输出结果的顺序。
27 | *
28 | * @author 刘壮飞
29 | * https://github.com/zfman.
30 | * https://blog.csdn.net/lzhuangfei.
31 | */
32 | public class Solution349 {
33 | /**
34 | * 利用哈希表或者
35 | * 先排序后使用双指针,如果指针指向相同,说明出现一个交集元素
36 | *
37 | * @param nums1
38 | * @param nums2
39 | * @return
40 | */
41 | public int[] intersection(int[] nums1, int[] nums2) {
42 | HashMap map = new HashMap();
43 | Set set = new HashSet<>();//去重
44 | for (int i = 0; i < nums1.length; i++) {
45 | if (!map.containsKey(nums1[i])) map.put(nums1[i], 0);
46 | else map.put(nums1[i], map.get(nums1[i]) + 1);
47 | }
48 |
49 | for (int i = 0; i < nums2.length; i++) {
50 | if (map.containsKey(nums2[i])) {
51 | set.add(nums2[i]);
52 | }
53 | }
54 |
55 | int[] r = new int[set.size()];
56 | int i = 0;
57 | for (Integer val : set) {
58 | r[i++] = val;
59 | }
60 | return r;
61 | }
62 |
63 | public static void main(String[] args) {
64 | int[] nums1 = {
65 | 4, 9, 5
66 | };
67 | int[] nums2 = {
68 | 9, 4, 9, 8, 4
69 | };
70 | int[] r = new Solution349().intersection(nums1, nums2);
71 | ArrayUtils.printArray(r);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution301_400/Solution354.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution301_400;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * 354. 俄罗斯套娃信封问题
7 | *
8 | * 给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
9 | *
10 | * 请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
11 | *
12 | * 说明:
13 | * 不允许旋转信封。
14 | *
15 | * 示例:
16 | *
17 | * 输入: envelopes = [[5,4],[6,4],[6,7],[2,3]]
18 | * 输出: 3
19 | * 解释: 最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。
20 | *
21 | * @author 刘壮飞
22 | * https://github.com/zfman.
23 | * https://blog.csdn.net/lzhuangfei.
24 | */
25 | public class Solution354 {
26 |
27 | /**
28 | * 先对宽度递增排序,然后对高度计算“最长递增子序列的长度”
29 | * @param envelopes
30 | * @return
31 | */
32 | public int maxEnvelopes(int[][] envelopes) {
33 | if (envelopes.length == 0) return 0;
34 | int[] dp = new int[envelopes.length];
35 | Arrays.fill(dp, 1);
36 | sort(envelopes);
37 | int max = 1;
38 | for (int i = 1; i < envelopes.length; i++) {
39 | for (int j = 0; j < i; j++) {
40 | if (envelopes[i][0]>envelopes[j][0]&&envelopes[i][1] > envelopes[j][1]) {
41 | dp[i] = Math.max(dp[i], dp[j] + 1);
42 | }
43 | }
44 | if (dp[i] > max) max = dp[i];
45 | }
46 | return max;
47 | }
48 |
49 | public void sort(int[][] envelopes) {
50 | for (int i = 0; i < envelopes.length - 1; i++) {
51 | for (int j = i + 1; j < envelopes.length; j++) {
52 | if (envelopes[i][0] > envelopes[j][0]) {
53 | int[] tmp = envelopes[i];
54 | envelopes[i] = envelopes[j];
55 | envelopes[j] = tmp;
56 | }
57 | }
58 | }
59 | }
60 |
61 | public static void main(String[] args) {
62 | int[][] envelopes = {
63 | {5,4},{6,4},{6,7},{2,3}
64 | };
65 | // 2,4 5,4 6,4 6,7
66 | // 1 1 1 1
67 |
68 | int r = new Solution354().maxEnvelopes(envelopes);
69 | System.out.println(r);
70 | }
71 |
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution301_400/Solution383.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution301_400;
2 |
3 | /**
4 | * 383. 赎金信
5 | *
6 | * 给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成。如果可以构成,返回 true ;否则返回 false。
7 | *
8 | * (题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。)
9 | *
10 | * 注意:
11 | *
12 | * 你可以假设两个字符串均只含有小写字母。
13 | *
14 | * canConstruct("a", "b") -> false
15 | * canConstruct("aa", "ab") -> false
16 | * canConstruct("aa", "aab") -> true
17 | *
18 | * @author 刘壮飞
19 | * https://github.com/zfman.
20 | * https://blog.csdn.net/lzhuangfei.
21 | */
22 | public class Solution383 {
23 | public boolean canConstruct(String ransomNote, String magazine) {
24 | int[] a=new int[26];
25 | for(char ch:magazine.toCharArray()){
26 | a[ch-'a']++;
27 | }
28 | for(char ch:ransomNote.toCharArray()){
29 | a[ch-'a']--;
30 | }
31 |
32 | for(int i=0;i 3
32 | * 2. 5 -> 2 -> 1
33 | * 3. -3 -> 11
34 | *
35 | * @author 刘壮飞
36 | * https://github.com/zfman.
37 | * https://blog.csdn.net/lzhuangfei.
38 | */
39 | public class Solution437 {
40 | private int pathCount=0;
41 |
42 | public int pathSum(TreeNode root, int sum) {
43 | todo(root,sum);
44 | return pathCount;
45 | }
46 |
47 | /**
48 | * 以root为起始点开始计算路径长度
49 | * @param root
50 | * @param sum
51 | */
52 | public void todo(TreeNode root, int sum) {
53 | if(root!=null){
54 | doThing(root,sum,0);
55 | todo(root.left,sum);
56 | todo(root.right,sum);
57 | }
58 | }
59 |
60 | public void doThing(TreeNode node, int sum,int now) {
61 | if(node==null) return;
62 | if(now+node.val==sum) pathCount++;
63 | if(node.left!=null||node.right!=null){
64 | doThing(node.left,sum,now+node.val);
65 | doThing(node.right,sum,now+node.val);
66 | }
67 | }
68 |
69 | public static void main(String[] args){
70 | // sout:3
71 | TreeNode root=TreeUtils.stringToTreeWith("5 4 11 7 # # 2 # # # 8 13 # # 4 5 # # 1 # #"," ");
72 | int sum=22;
73 | int r=new Solution437().pathSum(root,sum);
74 | System.out.println(r);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution401_500/Solution442.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution401_500;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 442. 数组中重复的数据
8 | *
9 | * 给定一个整数数组 a,其中1 ≤ a[i] ≤ n (n为数组长度), 其中有些元素出现两次而其他元素出现一次。
10 | *
11 | * 找到所有出现两次的元素。
12 | *
13 | * 你可以不用到任何额外空间并在O(n)时间复杂度内解决这个问题吗?
14 | *
15 | * 示例:
16 | *
17 | * 输入:
18 | * [4,3,2,7,8,2,3,1]
19 | *
20 | * 输出:
21 | * [2,3]
22 | *
23 | * @author 刘壮飞
24 | * https://github.com/zfman.
25 | * https://blog.csdn.net/lzhuangfei.
26 | */
27 | public class Solution442 {
28 |
29 | /**
30 | * 使用桶排序的思想(不需要排序).
31 | * 这句话是关键:1 ≤ a[i] ≤ n (n为数组长度),
32 | * v[i]:桶,下标与nums[i]值对应
33 | *
34 | * @param nums
35 | * @return
36 | */
37 | public List findDuplicates(int[] nums) {
38 | List r = new ArrayList<>();
39 | int[] v=new int[nums.length+1];
40 | for (int i = 0; i < nums.length; i++) {
41 | v[nums[i]]++;
42 | }
43 | for(int i=1;i=2) r.add(i);
45 | }
46 | return r;
47 | }
48 |
49 | public static void main(String[] args) {
50 | int[] nums = {
51 | 4, 3, 2, 7, 8, 2, 3, 1
52 | };
53 | List r = new Solution442().findDuplicates(nums);
54 | for (Integer i : r) {
55 | System.out.print(i + " ");
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution401_500/Solution443.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution401_500;
2 |
3 | /**
4 | * 443. 压缩字符串
5 | *
6 | * 给定一组字符,使用原地算法将其压缩。
7 | *
8 | * 压缩后的长度必须始终小于或等于原数组长度。
9 | *
10 | * 数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。
11 | *
12 | * 在完成原地修改输入数组后,返回数组的新长度。
13 | *
14 | *
15 | *
16 | * 进阶:
17 | * 你能否仅使用O(1) 空间解决问题?
18 | *
19 | *
20 | *
21 | * 示例 1:
22 | *
23 | * 输入:
24 | * ["a","a","b","b","c","c","c"]
25 | *
26 | * 输出:
27 | * 返回6,输入数组的前6个字符应该是:["a","2","b","2","c","3"]
28 | *
29 | * 说明:
30 | * "aa"被"a2"替代。"bb"被"b2"替代。"ccc"被"c3"替代。
31 | * 示例 2:
32 | *
33 | * 输入:
34 | * ["a"]
35 | *
36 | * 输出:
37 | * 返回1,输入数组的前1个字符应该是:["a"]
38 | *
39 | * 说明:
40 | * 没有任何字符串被替代。
41 | * 示例 3:
42 | *
43 | * 输入:
44 | * ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
45 | *
46 | * 输出:
47 | * 返回4,输入数组的前4个字符应该是:["a","b","1","2"]。
48 | *
49 | * 说明:
50 | * 由于字符"a"不重复,所以不会被压缩。"bbbbbbbbbbbb"被“b12”替代。
51 | * 注意每个数字在数组中都有它自己的位置。
52 | * 注意:
53 | *
54 | * 所有字符都有一个ASCII值在[35, 126]区间内。
55 | * 1 <= len(chars) <= 1000。
56 | *
57 | * @author 刘壮飞
58 | * https://github.com/zfman.
59 | * https://blog.csdn.net/lzhuangfei.
60 | */
61 | public class Solution443 {
62 | /**
63 | * 该算法没有满足题目要求,空间占用不是O(1)
64 | * 思路:
65 | * 遍历,计算重复字符的长度,遇到和上个字符相同时,令计数器+1
66 | * 遇到不同时,令上次相同的字符和长度组合为一个字符串,加入到str中
67 | * 遍历结束后令上次相同的字符和长度组合为一个字符串,加入到str中
68 | *
69 | * @param chars
70 | * @return
71 | */
72 | public int compress(char[] chars) {
73 | if(chars.length==1) return 1;
74 |
75 | //得出str
76 | char ch=chars[0];
77 | String str="";
78 | int c=1;
79 | for(int i=1;i1) str+=ch+""+c;
84 | else str+=ch;
85 | c=1;
86 | }
87 | ch=chars[i];
88 | }
89 | //最后匹配到存储到str
90 | if(c>1) str+=ch+""+c;
91 | else str+=ch;
92 |
93 | //修改chars数组的值
94 | for(int i=0;i findDuplicates(int[] nums) {
38 | List r = new ArrayList<>();
39 | int[] v=new int[nums.length+1];
40 | for (int i = 0; i < nums.length; i++) {
41 | v[nums[i]]++;
42 | }
43 | for(int i=1;i r = new Solution448().findDuplicates(nums);
54 | for (Integer i : r) {
55 | System.out.print(i + " ");
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution401_500/Solution459.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution401_500;
2 |
3 | /**
4 | * 未完成
5 | * @author 刘壮飞
6 | * https://github.com/zfman.
7 | * https://blog.csdn.net/lzhuangfei.
8 | */
9 | public class Solution459 {
10 | public boolean repeatedSubstringPattern(String s) {
11 | for(int i=0;i='A'&&ch1<='Z'){
45 | if(ch2>='A'&&ch2<='Z'){
46 | type=1;
47 | }else type=2;
48 | }else{
49 | if(ch2>='A'&&ch2<='Z'){
50 | return false;
51 | }else type=2;
52 | }
53 |
54 | //遍历后续字符
55 | for(int i=2;i='a'&&ch<='z') return false;
59 | }else if(type==2){//后续字符全为小写
60 | if(ch>='A'&&ch<='Z') return false;
61 | }
62 | }
63 | return true;
64 | }
65 | public static void main(String[] args){
66 | String words="FlaG";
67 | boolean r=new Solution520().detectCapitalUse(words);
68 | System.out.println(r);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution541.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | /**
4 | * 541. 反转字符串 II
5 | *
6 | * 给定一个字符串和一个整数 k,你需要对从字符串开头算起的每个 2k 个字符的前k个字符进行反转。如果剩余少于 k 个字符,则将剩余的所有全部反转。如果有小于 2k 但大于或等于 k 个字符,则反转前 k 个字符,并将剩余的字符保持原样。
7 | *
8 | * 示例:
9 | *
10 | * 输入: s = "abcdefg", k = 2
11 | * 输出: "bacdfeg"
12 | * 要求:
13 | *
14 | * 该字符串只包含小写的英文字母。
15 | * 给定字符串的长度和 k 在[1, 10000]范围内。
16 | *
17 | * @author 刘壮飞
18 | * https://github.com/zfman.
19 | * https://blog.csdn.net/lzhuangfei.
20 | */
21 | public class Solution541 {
22 | public String reverseStr(String s, int k) {
23 | if(s==null||s.equals("")) return "";
24 | if(s.length()=0;i--){
36 | str+=s.charAt(i);
37 | }
38 | return str;
39 | }
40 |
41 | public static void main(String[] args) {
42 | String s = "abcdefg";
43 | int k = 2;
44 | String r = new Solution541().reverseStr(s, k);
45 | System.out.println(r);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution543.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | import leetcode.common.TreeNode;
4 | import leetcode.common.TreeUtils;
5 |
6 | /**
7 | * 543. 二叉树的直径
8 | *
9 | * 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。
10 | *
11 | * 示例 :
12 | * 给定二叉树
13 | *
14 | * 1
15 | * / \
16 | * 2 3
17 | * / \
18 | * 4 5
19 | * 返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
20 | *
21 | * 注意:两结点之间的路径长度是以它们之间边的数目表示。
22 | *
23 | * @author 刘壮飞
24 | * https://github.com/zfman.
25 | * https://blog.csdn.net/lzhuangfei.
26 | */
27 | public class Solution543 {
28 | private int maxVal=0;
29 | public int diameterOfBinaryTree(TreeNode root) {
30 | todo(root);
31 | return maxVal;
32 | }
33 |
34 | /**
35 | * 以root为起始点,计算左右子树的深度之和,记录最大值
36 | * @param root
37 | */
38 | public void todo(TreeNode root) {
39 | if(root!=null){
40 | int v=depth(root.left)+depth(root.right);
41 | if(v>maxVal) maxVal=v;
42 | todo(root.left);
43 | todo(root.right);
44 | }
45 | }
46 |
47 | /**
48 | * 求解树深度
49 | * @param root
50 | * @return
51 | */
52 | public int depth(TreeNode root) {
53 | if(root==null) return 0;
54 | return Math.max(depth(root.left),depth(root.right))+1;
55 | }
56 |
57 | public static void main(String[] args){
58 | TreeNode root=TreeUtils.stringToTree("124##5##3##");
59 | int r=new Solution543().diameterOfBinaryTree(root);
60 | System.out.println(r);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution551.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | /**
4 | * 551. 学生出勤纪录 I
5 | *
6 | * 给定一个字符串来代表一个学生的出勤纪录,这个纪录仅包含以下三个字符:
7 | *
8 | * 'A' : Absent,缺勤
9 | * 'L' : Late,迟到
10 | * 'P' : Present,到场
11 | * 如果一个学生的出勤纪录中不超过一个'A'(缺勤)并且不超过两个连续的'L'(迟到),那么这个学生会被奖赏。
12 | *
13 | * 你需要根据这个学生的出勤纪录判断他是否会被奖赏。
14 | *
15 | * 示例 1:
16 | *
17 | * 输入: "PPALLP"
18 | * 输出: True
19 | * 示例 2:
20 | *
21 | * 输入: "PPALLL"
22 | * 输出: False
23 | *
24 | * @author 刘壮飞
25 | * https://github.com/zfman.
26 | * https://blog.csdn.net/lzhuangfei.
27 | */
28 | public class Solution551 {
29 |
30 | public boolean checkRecord(String s) {
31 | int aCount=0;//char A count
32 | int sameCount=0; //same char count
33 |
34 | for(int i=0;i2) break;
40 | }
41 | return aCount<=1&&sameCount<=2;
42 | }
43 |
44 | public static void main(String[] args) {
45 | String s = "PPALLP";
46 | boolean r = new Solution551().checkRecord(s);
47 | System.out.println(r);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution557.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | /**
4 | * 557. 反转字符串中的单词 III
5 | *
6 | * 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
7 | *
8 | * 示例 1:
9 | *
10 | * 输入: "Let's take LeetCode contest"
11 | * 输出: "s'teL ekat edoCteeL tsetnoc"
12 | * 注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。
13 | *
14 | * @author 刘壮飞
15 | * https://github.com/zfman.
16 | * https://blog.csdn.net/lzhuangfei.
17 | */
18 | public class Solution557 {
19 | public String reverseWords(String s) {
20 | String[] arr=s.split(" ");
21 | String str="";
22 | for(int i=0;i=0;i--){
31 | str+=s.charAt(i);
32 | }
33 | return str;
34 | }
35 |
36 | public static void main(String[] args) {
37 | String s = "Let's take LeetCode contest";
38 | String r = new Solution557().reverseWords(s);
39 | System.out.println(r);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution559.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 559. N叉树的最大深度
8 | *
9 | * 给定一个N叉树,找到其最大深度。
10 | *
11 | * 最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
12 | *
13 | * 例如,给定一个 3叉树 :
14 | *
15 | * https://leetcode-cn.com/static/images/problemset/NaryTreeExample.png
16 | *
17 | * 我们应返回其最大深度,3。
18 | *
19 | * 说明:
20 | *
21 | * 树的深度不会超过 1000。
22 | * 树的节点总不会超过 5000。
23 | *
24 | * @author 刘壮飞
25 | * https://github.com/zfman.
26 | * https://blog.csdn.net/lzhuangfei.
27 | */
28 | public class Solution559 {
29 | public int maxDepth(Node root) {
30 | if(root==null) return 0;
31 | if(root.children==null) return 1;
32 | int max=0;
33 | for(Node node:root.children){
34 | int t=maxDepth(node);
35 | if(t>max) max=t;
36 | }
37 | return max+1;
38 | }
39 |
40 | public static void main(String[] args){
41 | Node node5=new Node(5,null);
42 | Node node6=new Node(6,null);
43 | List children3=new ArrayList<>();
44 | children3.add(node5);
45 | children3.add(node6);
46 |
47 | Node node3=new Node(3,children3);
48 | Node node2=new Node(2,null);
49 | Node node4=new Node(4,null);
50 |
51 | List children1=new ArrayList<>();
52 | children1.add(node3);
53 | children1.add(node2);
54 | children1.add(node4);
55 | Node root=new Node(1,children1);
56 |
57 | int r=new Solution559().maxDepth(root);
58 | System.out.println(r);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution563.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | import leetcode.common.TreeNode;
4 | import leetcode.common.TreeUtils;
5 |
6 | /**
7 | * 563. 二叉树的坡度
8 | *
9 | * 给定一个二叉树,计算整个树的坡度。
10 | *
11 | * 一个树的节点的坡度定义即为,该节点左子树的结点之和和右子树结点之和的差的绝对值。空结点的的坡度是0。
12 | *
13 | * 整个树的坡度就是其所有节点的坡度之和。
14 | *
15 | * 示例:
16 | *
17 | * 输入:
18 | * 1
19 | * / \
20 | * 2 3
21 | * 输出: 1
22 | * 解释:
23 | * 结点的坡度 2 : 0
24 | * 结点的坡度 3 : 0
25 | * 结点的坡度 1 : |2-3| = 1
26 | * 树的坡度 : 0 + 0 + 1 = 1
27 | * 注意:
28 | *
29 | * 任何子树的结点的和不会超过32位整数的范围。
30 | * 坡度的值不会超过32位整数的范围。
31 | *
32 | * @author 刘壮飞
33 | * https://github.com/zfman.
34 | * https://blog.csdn.net/lzhuangfei.
35 | */
36 | public class Solution563 {
37 | /**
38 | * 计算各个节点的坡度和
39 | * @param root
40 | * @return
41 | */
42 | public int findTilt(TreeNode root) {
43 | if(root==null) return 0;
44 | return findTilt(root.left)+findTilt(root.right)+Math.abs(todo(root.left)-todo(root.right));
45 | }
46 |
47 | /**
48 | * 计算以root为起始点的坡度值
49 | * @param root
50 | * @return
51 | */
52 | public int todo(TreeNode root) {
53 | if(root==null) return 0;
54 | if(root.left==null&&root.right==null){
55 | return root.val;
56 | }
57 | return root.val+todo(root.left)+todo(root.right);
58 | }
59 |
60 | public static void main(String[] args){
61 | TreeNode root=TreeUtils.stringToTree("124###35###");
62 | int r=new Solution563().findTilt(root);
63 | System.out.println(r);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution572.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | import leetcode.common.TreeNode;
4 | import leetcode.common.TreeUtils;
5 |
6 | /**
7 | * 572. 另一个树的子树
8 | *
9 | * 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
10 | *
11 | * 示例 1:
12 | * 给定的树 s:
13 | *
14 | * 3
15 | * / \
16 | * 4 5
17 | * / \
18 | * 1 2
19 | * 给定的树 t:
20 | *
21 | * 4
22 | * / \
23 | * 1 2
24 | * 返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。
25 | *
26 | * 示例 2:
27 | * 给定的树 s:
28 | *
29 | * 3
30 | * / \
31 | * 4 5
32 | * / \
33 | * 1 2
34 | * /
35 | * 0
36 | * 给定的树 t:
37 | *
38 | * 4
39 | * / \
40 | * 1 2
41 | * 返回 false。
42 | *
43 | * @author 刘壮飞
44 | * https://github.com/zfman.
45 | * https://blog.csdn.net/lzhuangfei.
46 | */
47 | public class Solution572 {
48 | public boolean isSubtree(TreeNode s, TreeNode t) {
49 | return s!=null&&(isSubtree(s.left,t)||isSubtree(s.right,t)||isSample(s,t));
50 | }
51 |
52 | public boolean isSample(TreeNode s, TreeNode t) {
53 | if(s==null&&t==null) return true;
54 | else if(s==null||t==null) return false;
55 | else{
56 | return s.val==t.val&&isSample(s.left,t.left)&&isSample(s.right,t.right);
57 | }
58 | }
59 |
60 | public static void main(String[] args){
61 | TreeNode s=TreeUtils.stringToTree("341##2##5##");
62 | TreeNode t=TreeUtils.stringToTree("41##2##");
63 | boolean r=new Solution572().isSubtree(s,t);
64 | System.out.println(r);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution589.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 589. N叉树的前序遍历(未使用迭代算法)
8 | *
9 | * 给定一个N叉树,返回其节点值的前序遍历。
10 | *
11 | * 例如,给定一个 3叉树 :
12 | *
13 | * https://leetcode-cn.com/static/images/problemset/NaryTreeExample.png
14 | *
15 | * 返回其前序遍历: [1,3,5,6,2,4]。
16 | * 说明: 递归法很简单,你可以使用迭代法完成此题吗?
17 | *
18 | * @author 刘壮飞
19 | * https://github.com/zfman.
20 | * https://blog.csdn.net/lzhuangfei.
21 | */
22 | class Solution589 {
23 |
24 | public List preorder(Node root) {
25 | List list=new ArrayList<>();
26 | todo(root,list);
27 | return list;
28 | }
29 |
30 | public void todo(Node root,List list) {
31 | if(root!=null){
32 | list.add(root.val);
33 | if(root.children!=null){
34 | for(Node node:root.children){
35 | todo(node,list);
36 | }
37 | }
38 | }
39 | }
40 |
41 | public static void main(String[] args){
42 | Node node5=new Node(5,null);
43 | Node node6=new Node(6,null);
44 | List children3=new ArrayList<>();
45 | children3.add(node5);
46 | children3.add(node6);
47 |
48 | Node node3=new Node(3,children3);
49 | Node node2=new Node(2,null);
50 | Node node4=new Node(4,null);
51 |
52 | List children1=new ArrayList<>();
53 | children1.add(node3);
54 | children1.add(node2);
55 | children1.add(node4);
56 | Node root=new Node(1,children1);
57 |
58 | List r=new Solution589().preorder(root);
59 | for(Integer i:r){
60 | System.out.print(i+" ");
61 | }
62 |
63 | }
64 | }
65 |
66 | class Node {
67 | public int val;
68 | public List children;
69 |
70 | public Node() {}
71 |
72 | public Node(int _val,List _children) {
73 | val = _val;
74 | children = _children;
75 | }
76 | };
77 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution501_600/Solution590.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution501_600;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 590. N叉树的后序遍历(未使用迭代算法)
8 | *
9 | * 给定一个N叉树,返回其节点值的后序遍历。
10 | *
11 | * 例如,给定一个 3叉树 :
12 | *
13 | * https://leetcode-cn.com/static/images/problemset/NaryTreeExample.png
14 | *
15 | * 返回其后序遍历: [5,6,3,2,4,1].
16 | * 说明: 递归法很简单,你可以使用迭代法完成此题吗?
17 | *
18 | * @author 刘壮飞
19 | * https://github.com/zfman.
20 | * https://blog.csdn.net/lzhuangfei.
21 | */
22 | class Solution590 {
23 |
24 | public List postorder(Node root) {
25 | List list=new ArrayList<>();
26 | todo(root,list);
27 | return list;
28 | }
29 |
30 | public void todo(Node root,List list) {
31 | if(root!=null){
32 | if(root.children!=null){
33 | for(Node node:root.children){
34 | todo(node,list);
35 | }
36 | }
37 | list.add(root.val);
38 | }
39 | }
40 |
41 | public static void main(String[] args){
42 | Node node5=new Node(5,null);
43 | Node node6=new Node(6,null);
44 | List children3=new ArrayList<>();
45 | children3.add(node5);
46 | children3.add(node6);
47 |
48 | Node node3=new Node(3,children3);
49 | Node node2=new Node(2,null);
50 | Node node4=new Node(4,null);
51 |
52 | List children1=new ArrayList<>();
53 | children1.add(node3);
54 | children1.add(node2);
55 | children1.add(node4);
56 | Node root=new Node(1,children1);
57 |
58 | List r=new Solution590().postorder(root);
59 | for(Integer i:r){
60 | System.out.print(i+" ");
61 | }
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution601_700/Solution606.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution601_700;
2 |
3 | import leetcode.common.TreeNode;
4 | import leetcode.common.TreeUtils;
5 |
6 | /**
7 | * 606. 根据二叉树创建字符串
8 | *
9 | * 你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。
10 | *
11 | * 空节点则用一对空括号 "()" 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
12 | *
13 | * 示例 1:
14 | *
15 | * 输入: 二叉树: [1,2,3,4]
16 | * 1
17 | * / \
18 | * 2 3
19 | * /
20 | * 4
21 | *
22 | * 输出: "1(2(4))(3)"
23 | *
24 | * 解释: 原本将是“1(2(4)())(3())”,
25 | * 在你省略所有不必要的空括号对之后,
26 | * 它将是“1(2(4))(3)”。
27 | * 示例 2:
28 | *
29 | * 输入: 二叉树: [1,2,3,null,4]
30 | * 1
31 | * / \
32 | * 2 3
33 | * \
34 | * 4
35 | *
36 | * 输出: "1(2()(4))(3)"
37 | *
38 | * 解释: 和第一个示例相似,
39 | * 除了我们不能省略第一个对括号来中断输入和输出之间的一对一映射关系。
40 | *
41 | * @author 刘壮飞
42 | * https://github.com/zfman.
43 | * https://blog.csdn.net/lzhuangfei.
44 | */
45 | public class Solution606 {
46 | public String tree2str(TreeNode t) {
47 | if(t==null) return "";
48 | String left=tree2str(t.left);
49 | String right=tree2str(t.right);
50 |
51 | //叶子节点
52 | if(left.equals("")&&right.equals("")){
53 | return t.val+"";
54 | }
55 | //右子树为null
56 | else if(!left.equals("")&&right.equals("")){
57 | return t.val+"("+left+")";
58 | }
59 | //非叶子节点&&右子树不为null
60 | else {
61 | return t.val+"("+left+")("+right+")";
62 | }
63 | }
64 |
65 | public static void main(String[] args){
66 | TreeNode t=TreeUtils.stringToTree("123##4###");
67 | String s=new Solution606().tree2str(t);
68 | System.out.println(s);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution601_700/Solution653.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution601_700;
2 |
3 | import leetcode.common.TreeNode;
4 | import leetcode.common.TreeUtils;
5 |
6 | import java.util.HashSet;
7 | import java.util.Set;
8 |
9 | /**
10 | * 653. 两数之和 IV - 输入 BST
11 | *
12 | * 给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
13 | *
14 | * 案例 1:
15 | *
16 | * 输入:
17 | * 5
18 | * / \
19 | * 3 6
20 | * / \ \
21 | * 2 4 7
22 | *
23 | * Target = 9
24 | *
25 | * 输出: True
26 | *
27 | *
28 | * 案例 2:
29 | *
30 | * 输入:
31 | * 5
32 | * / \
33 | * 3 6
34 | * / \ \
35 | * 2 4 7
36 | *
37 | * Target = 28
38 | *
39 | * 输出: False
40 | *
41 | * @author 刘壮飞
42 | * https://github.com/zfman.
43 | * https://blog.csdn.net/lzhuangfei.
44 | */
45 | public class Solution653 {
46 |
47 | /**
48 | * 我的思路是:把树中元素存储到集合中,然后对集合二重循环求解和
49 | *
50 | * 以下是别人的思路,代码很简洁高效,学习学习
51 | *
52 | * @param root
53 | * @param k
54 | * @return
55 | */
56 | public boolean findTarget(TreeNode root, int k) {
57 | Set set=new HashSet<>();
58 | return todo(root,k,set);
59 | }
60 |
61 | public boolean todo(TreeNode root, int k, Set set) {
62 | if(root==null) return false;
63 | if(set.contains(k-root.val)) return true;
64 | set.add(root.val);
65 | return todo(root.left,k,set)||todo(root.right,k,set);
66 | }
67 |
68 | public static void main(String[] args){
69 | TreeNode root=TreeUtils.stringToTree("532##4##6#7##");
70 | boolean r=new Solution653().findTarget(root,9);
71 | System.out.println(r);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/leetcode/all/solution601_700/Solution684.java:
--------------------------------------------------------------------------------
1 | package leetcode.all.solution601_700;
2 |
3 | import utils.ArrayUtils;
4 |
5 | /**
6 | * 684. 冗余连接
7 | *
8 | * 在本问题中, 树指的是一个连通且无环的无向图。
9 | *
10 | * 输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。
11 | *
12 | * 结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。
13 | *
14 | * 返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。
15 | *
16 | * 示例 1:
17 | *
18 | * 输入: [[1,2], [1,3], [2,3]]
19 | * 输出: [2,3]
20 | * 解释: 给定的无向图为:
21 | * 1
22 | * / \
23 | * 2 - 3
24 | * 示例 2:
25 | *
26 | * 输入: [[1,2], [2,3], [3,4], [1,4], [1,5]]
27 | * 输出: [1,4]
28 | * 解释: 给定的无向图为:
29 | * 5 - 1 - 2
30 | * | |
31 | * 4 - 3
32 | * 注意:
33 | *
34 | * 输入的二维数组大小在 3 到 1000。
35 | * 二维数组中的整数在1到N之间,其中N是输入数组的大小。
36 | *
37 | * @author 刘壮飞
38 | * https://github.com/zfman.
39 | * https://blog.csdn.net/lzhuangfei.
40 | */
41 | public class Solution684 {
42 | public int[] findRedundantConnection(int[][] edges) {
43 | int[] union=new int[edges.length+1];//映射关系
44 | int[] r=new int[2];//返回结果
45 | for(int i=0;inums.length) return false;
28 | int sum=0;
29 | for(int i=0;itarget) return false;
39 | if(k==0&&nums.length==number) return true;
40 | if(curSum==target) return todo(nums,k-1,0,0,target,v,number);
41 | for(int i=start;i list1=new ArrayList<>();
33 | List list2=new ArrayList<>();
34 | todo(root1,list1);
35 | todo(root2,list2);
36 | if(list1.toString().equals(list2.toString())) return true;
37 | return false;
38 | }
39 |
40 | public void todo(TreeNode root, List list) {
41 | if(root!=null){
42 | if(root.left==null&&root.right==null){
43 | list.add(root.val);
44 | }
45 | todo(root.left,list);
46 | todo(root.right,list);
47 | }
48 | }
49 |
50 | public static void main(String[] args){
51 | TreeNode root1=TreeUtils.stringToTree("12##3##");
52 | TreeNode root2=TreeUtils.stringToTree("13##2##");
53 | boolean b=new Solution872().leafSimilar(root1,root2);
54 | System.out.println(b);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/leetcode/common/AMGraph.java:
--------------------------------------------------------------------------------
1 | package leetcode.common;
2 |
3 | /**
4 | * 临界矩阵存储图
5 | * @author 刘壮飞
6 | * https://github.com/zfman.
7 | * https://blog.csdn.net/lzhuangfei.
8 | */
9 | public class AMGraph {
10 | public int[][] arcs;
11 | public int vexNum;
12 | public int arcNum;
13 | }
14 |
--------------------------------------------------------------------------------
/src/leetcode/common/GraphUtils.java:
--------------------------------------------------------------------------------
1 | package leetcode.common;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class GraphUtils {
11 |
12 | /**
13 | * 无向图输入
14 | */
15 | public static AMGraph cin(){
16 | Scanner scanner = new Scanner(System.in);
17 | System.out.println("顶点数 边数:");
18 | int vexNum = scanner.nextInt();
19 | int arcNum = scanner.nextInt();
20 |
21 | int[] vexs = new int[vexNum + 1];
22 | int[][] arcs = new int[vexNum + 1][vexNum + 1];
23 | for (int i = 1; i <= vexNum; i++) {
24 | vexs[i] = i;
25 | }
26 |
27 | System.out.println("顶点1 顶点2(表示1-2有一条边):");
28 | for (int i = 1; i <= arcNum; i++) {
29 | int pos1 = scanner.nextInt();
30 | int pos2 = scanner.nextInt();
31 | arcs[pos1][pos2] = 1;
32 | arcs[pos2][pos1] = 1;
33 | }
34 |
35 | AMGraph graph=new AMGraph();
36 | graph.arcs=arcs;
37 | graph.vexNum=vexNum;
38 | graph.arcNum=arcNum;
39 |
40 | return graph;
41 | }
42 |
43 | /**
44 | * 输出
45 | * @param graph
46 | */
47 | public static void print(AMGraph graph){
48 | if(graph.arcs==null) return;
49 | int[][] arcs=graph.arcs;
50 | for (int i = 1; i < arcs.length; i++) {
51 | for (int j = 1; j < arcs[i].length; j++)
52 | System.out.print(arcs[i][j] + " ");
53 | System.out.println();
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/leetcode/common/LinkedUtils.java:
--------------------------------------------------------------------------------
1 | package leetcode.common;
2 |
3 | /**
4 | * 链表工具类
5 | * @author 刘壮飞
6 | * https://github.com/zfman.
7 | * https://blog.csdn.net/lzhuangfei.
8 | */
9 | public class LinkedUtils {
10 |
11 | /**
12 | * 数组转化为链表
13 | * @param array
14 | * @return
15 | */
16 | public static ListNode arrayToLinkedList(int[] array){
17 | if(array==null) return null;
18 | //head node
19 | ListNode root=new ListNode(-1);
20 | ListNode p=root;
21 |
22 | int size=array.length;
23 | int i=0;
24 | while(i");
45 | }
46 | root=root.next;
47 | }
48 | System.out.println();
49 | }
50 | }
51 |
52 | /**
53 | * 求链表长度
54 | * @param root
55 | * @return
56 | */
57 | public static int length(ListNode root) {
58 | if(root==null) return 0;
59 | int n=0;
60 | while(root!=null){
61 | root=root.next;
62 | n++;
63 | }
64 | return n;
65 | }
66 |
67 | /**
68 | * 返回指向链表尾部的指针
69 | * @param root
70 | * @return
71 | */
72 | public static ListNode moveToTail(ListNode root) {
73 | if(root==null) return null;
74 | ListNode tail=root;
75 | while(tail.next!=null){
76 | tail=tail.next;
77 | }
78 | return tail;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/leetcode/common/ListNode.java:
--------------------------------------------------------------------------------
1 | package leetcode.common;
2 |
3 | public class ListNode {
4 | public int val;
5 | public ListNode next;
6 |
7 | public ListNode(int val) {
8 | this.val=val;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/leetcode/common/OtherUtils.java:
--------------------------------------------------------------------------------
1 | package leetcode.common;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class OtherUtils {
9 | // 最大公约数
10 | public static int get_gcd(int a, int b) {
11 | int max, min;
12 | min=Math.min(a,b);
13 | max=Math.max(a,b);
14 |
15 | if (max % min != 0) {
16 | return get_gcd(min, max % min);
17 | } else
18 | return min;
19 |
20 | }
21 |
22 | // 最小公倍数
23 | public static int get_lcm(int a, int b) {
24 | return a * b / get_gcd(a, b);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/leetcode/common/TreeNode.java:
--------------------------------------------------------------------------------
1 | package leetcode.common;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class TreeNode {
9 | public int val;
10 | public TreeNode left;
11 | public TreeNode right;
12 |
13 | public TreeNode(int x) {
14 | val = x;
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/leetcode/common/TreeUtils.java:
--------------------------------------------------------------------------------
1 | package leetcode.common;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class TreeUtils {
11 |
12 | public static int k=0;
13 |
14 | public static int k2=0;
15 |
16 | /**
17 | * 根据string创建树:节点的值小于等于9
18 | *
19 | *
20 | * @param s 先序的序列,空使用#表示
21 | * @return
22 | */
23 | public static TreeNode stringToTree(String s){
24 | k=0;
25 | TreeNode root=null;
26 | root=createTree(root,s);
27 | return root;
28 | }
29 |
30 | private static TreeNode createTree(TreeNode node,String s){
31 | char ch=s.charAt(k++);
32 | if(ch=='#') return null;
33 | else{
34 | node=new TreeNode(ch-'0');
35 | node.left=createTree(node.left,s);
36 | node.right=createTree(node.right,s);
37 | return node;
38 | }
39 | }
40 |
41 | /**
42 | * 符号以空格分隔,节点上的值可以大于9
43 | * @param str
44 | * @return
45 | */
46 | public static TreeNode stringToTreeWith(String str,String separator){
47 | k2=0;
48 | TreeNode root=null;
49 | String[] arr=str.trim().split(separator);
50 | root=createTreeWith(root,arr);
51 | return root;
52 | }
53 |
54 | private static TreeNode createTreeWith(TreeNode node,String[] arr){
55 | String v=arr[k2++];
56 | if(v.equals("#")) return null;
57 | else{
58 | node=new TreeNode(Integer.valueOf(v));
59 | node.left=createTreeWith(node.left,arr);
60 | node.right=createTreeWith(node.right,arr);
61 | return node;
62 | }
63 | }
64 |
65 | /**
66 | * 先序遍历
67 | * @param root
68 | */
69 | public static void travser(TreeNode root){
70 | if(root!=null){
71 | System.out.print(root.val+" ");
72 | travser(root.left);
73 | travser(root.right);
74 | }
75 | }
76 |
77 | /**
78 | * 中序遍历
79 | * @param root
80 | */
81 | public static void travser2(TreeNode root){
82 | if(root!=null){
83 | travser2(root.left);
84 | System.out.print(root.val+" ");
85 | travser2(root.right);
86 | }
87 | }
88 |
89 | /**
90 | * 后序遍历
91 | * @param root
92 | */
93 | public static void travser3(TreeNode root){
94 | if(root!=null){
95 | travser3(root.left);
96 | travser3(root.right);
97 | System.out.print(root.val+" ");
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/masai/GuShen.java:
--------------------------------------------------------------------------------
1 | package masai;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * 有股神吗?
7 | *
8 | * 有,小赛就是!
9 | *
10 | * 经过严密的计算,小赛买了一支股票,他知道从他买股票的那天开始,股票会有以下变化:第一天不变,以后涨一天,跌一天,涨两天,跌一天,涨三天,跌一天...依此类推。
11 | *
12 | * 为方便计算,假设每次涨和跌皆为1,股票初始单价也为1,请计算买股票的第n天每股股票值多少钱?
13 | *
14 | *
15 | *
16 | * 输入
17 | * 输入包括多组数据;
18 | *
19 | * 每行输入一个n,1<=n<=10^9 。
20 | *
21 | * 样例输入
22 | * 1
23 | *
24 | * 2
25 | *
26 | * 3
27 | *
28 | * 4
29 | *
30 | * 5
31 | *
32 | * 输出
33 | * 请输出他每股股票多少钱,对于每组数据,输出一行。
34 | *
35 | * 样例输出
36 | * 1
37 | *
38 | * 2
39 | *
40 | * 1
41 | *
42 | * 2
43 | *
44 | * 3
45 | *
46 | * 时间限制
47 | * C/C++语言:1000MS其它语言:3000MS
48 | * 内存限制
49 | * C/C++语言:65536KB其它语言:589824KB
50 | *
51 | *
52 | */
53 | public class GuShen {
54 |
55 | public static int doThing(int n){
56 | int i=0,k=2,j=2;
57 | while(kn){
34 | while(klist1.val){
23 | tmp.next=list1;
24 | tmp=tmp.next;
25 | list1=list1.next;
26 | }else {
27 | tmp.next=list2;
28 | tmp=tmp.next;
29 | list2=list2.next;
30 | }
31 | }
32 |
33 | if(list1==null){
34 | tmp.next=list2;
35 | }
36 | if(list2==null){
37 | tmp.next=list1;
38 | }
39 | return list3.next;
40 | }
41 |
42 | public static void main(String[] args){
43 | int[] arr1={
44 | 4,8,9
45 | };
46 | int[] arr2={
47 | 1,6,7
48 | };
49 | ListNode list1=LinkedUtils.arrayToLinkedList(arr1);
50 | ListNode list2=LinkedUtils.arrayToLinkedList(arr2);
51 |
52 | ListNode r=new MergeSolution().Merge(list1,list2);
53 | LinkedUtils.print(r);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/offer/MirrorSolution.java:
--------------------------------------------------------------------------------
1 | package offer;
2 |
3 | import leetcode.common.TreeNode;
4 | import leetcode.common.TreeUtils;
5 |
6 | /**
7 | * 二叉树的镜像
8 | *
9 | * 操作给定的二叉树,将其变换为源二叉树的镜像。
10 | * 输入描述:
11 | * 二叉树的镜像定义:源二叉树
12 | * 8
13 | * / \
14 | * 6 10
15 | * / \ / \
16 | * 5 7 9 11
17 | *
18 | * 镜像二叉树
19 | * 8
20 | * / \
21 | * 10 6
22 | * / \ / \
23 | * 11 9 7 5
24 | *
25 | *
26 | * @author 刘壮飞
27 | * https://github.com/zfman.
28 | * https://blog.csdn.net/lzhuangfei.
29 | */
30 | public class MirrorSolution {
31 | public void Mirror(TreeNode root) {
32 | if(root!=null){
33 | TreeNode tmp=root.left;
34 | root.left=root.right;
35 | root.right=tmp;
36 |
37 | Mirror(root.left);
38 | Mirror(root.right);
39 | }
40 | }
41 |
42 | public static void main(String[] args){
43 | String str="8,6,5,#,#,7,#,#,10,9,#,#,11,#,#";
44 | TreeNode root=TreeUtils.stringToTreeWith(str,",");
45 | new MirrorSolution().Mirror(root);
46 | TreeUtils.travser(root);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/offer/ReOrderArraySolution.java:
--------------------------------------------------------------------------------
1 | package offer;
2 |
3 | import utils.ArrayUtils;
4 |
5 | /**
6 | * 调整数组顺序使奇数位于偶数前面
7 | *
8 | * 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
9 | * 使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,
10 | * 并保证奇数和奇数,偶数和偶数之间的相对位置不变。
11 | *
12 | * @author 刘壮飞
13 | * https://github.com/zfman.
14 | * https://blog.csdn.net/lzhuangfei.
15 | */
16 | public class ReOrderArraySolution {
17 | public void reOrderArray(int [] array) {
18 | int n=array.length;
19 | int k=0;//已排好的奇数位置
20 | for(int i=0;ik){
24 | int tmp=array[j];
25 | array[j]=array[j-1];
26 | array[j-1]=tmp;
27 | j--;
28 | }
29 | k++;
30 | }
31 | }
32 | }
33 |
34 | public static void main(String[] args){
35 | //output:1,3,5,7,2,4,6
36 | int[] array={
37 | 1,2,3,4,5,6,7
38 | };
39 | new ReOrderArraySolution().reOrderArray(array);
40 | ArrayUtils.printArray(array);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/offer/RectCoverSolution.java:
--------------------------------------------------------------------------------
1 | package offer;
2 |
3 | /**
4 | * 矩形覆盖
5 | *
6 | * 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
7 | * 请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
8 | *
9 | * @author 刘壮飞
10 | * https://github.com/zfman.
11 | * https://blog.csdn.net/lzhuangfei.
12 | */
13 | public class RectCoverSolution {
14 | public int RectCover(int target) {
15 | if(target==0) return 0;
16 | if(target==1||target==2) return target;
17 | int i=3;
18 | int tmp1=1;
19 | int tmp2=2;
20 | int v=0;
21 | while (i<=target){
22 | v=tmp1+tmp2;
23 | tmp1=tmp2;
24 | tmp2=v;
25 | i++;
26 | }
27 | return v;
28 | }
29 |
30 | public static void main(String[] args) {
31 | int target=4;
32 | int r = new RectCoverSolution().RectCover(target);
33 | System.out.println(r);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/offer/ReverseListSolution.java:
--------------------------------------------------------------------------------
1 | package offer;
2 |
3 | import leetcode.common.LinkedUtils;
4 | import leetcode.common.ListNode;
5 | import sort.ArrayUtils;
6 |
7 | /**
8 | * 反转链表
9 | *
10 | * 输入一个链表,反转链表后,输出新链表的表头。
11 | *
12 | * @author 刘壮飞
13 | * https://github.com/zfman.
14 | * https://blog.csdn.net/lzhuangfei.
15 | */
16 | public class ReverseListSolution {
17 | public ListNode ReverseList(ListNode head) {
18 | if(head==null) return null;
19 | //pr:指向要反转的下一个元素
20 | //p:指向当前正在反转的元素
21 | //q:指向上一个反转的元素
22 | ListNode pr=head,p=head,q=null;
23 | while (pr!=null){
24 | pr=p.next;
25 | p.next=q;
26 | q=p;
27 | p=pr;
28 | }
29 |
30 | head=q;
31 | return head;
32 | }
33 |
34 | public static void main(String[] args){
35 | int[] array={
36 | 1,2,3,4,5,6
37 | };
38 | ListNode head=LinkedUtils.arrayToLinkedList(array);
39 | ListNode r=new ReverseListSolution().ReverseList(head);
40 | LinkedUtils.print(r);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/other/Baicizhan1.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 | import java.util.Scanner;
7 |
8 | /**
9 | * 时间相关
10 | * 给定两个时间,计算时针、分针、秒针走过的角度
11 | */
12 | public class Baicizhan1 {
13 | public static void main(String[] args){
14 | SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
15 | try {
16 | Scanner scanner=new Scanner(System.in);
17 | String str1=scanner.nextLine();
18 | String str2=scanner.nextLine();
19 |
20 | Date date1=sdf.parse("2018-09-20 "+str1);
21 | Date date2=sdf.parse("2018-09-20 "+str2);
22 |
23 | long d=date2.getTime()-date1.getTime();
24 |
25 | double hv=d/120000;
26 | double mv=d/10000;
27 | double mmv=d/1000*6;
28 | System.out.println((int)hv);
29 | System.out.println((int)mv);
30 | System.out.println((int)mmv);
31 | } catch (ParseException e) {
32 | e.printStackTrace();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/other/Baicizhan2.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | import utils.ArrayUtils;
4 |
5 | import java.util.Scanner;
6 |
7 | /**
8 | * 合并数字(未完成)
9 | * 连续三个数字以及以上可合并
10 | * 6
11 | * 1 2 3 4 6 7
12 | *
13 | * 输出:1-4 6 7
14 | */
15 | public class Baicizhan2 {
16 | public static void main(String[] args) {
17 | Scanner in = new Scanner(System.in);
18 | // int n=in.nextInt();
19 | // int[] arr=new int[n];
20 | // for(int i=0;i25){
49 | charIndex-=26;
50 | }
51 | return (char) (charIndex+65);
52 | }
53 |
54 | public static void main(String[] args){
55 | Scanner scanner=new Scanner(System.in);
56 | String str=scanner.nextLine();
57 | System.out.println(todo(str));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/other/Baidu2.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | /**
4 | * 生日蛋糕(未完成)
5 | * 时间限制:C/C++语言 1000MS;其他语言 3000MS
6 | * 内存限制:C/C++语言 65536KB;其他语言 589824KB
7 | * 题目描述:
8 | * 今天是明明的生日,他买了一个长方体形状的水果蛋糕,其顶面是N*M的矩阵,其中k*k个格子各有一片水果,参加他的生日派对的也有k*k个人,所以他要顺着矩阵的边线横着切k-1刀,竖着也切k-1刀,把蛋糕分成k*k份,每一份包含一片水果。请问他应该怎么切。
9 | *
10 | * 输入
11 | * 第一行三个整数N,M,k。(2≤k≤N, M≤50)
12 | *
13 | * 接下来k*k行,每行两个整数x,y,表示在蛋糕顶面的第x行第y列有一片水果。(1≤x≤N, 1≤y≤M)。数据保证不存在相同的 (x, y)。
14 | *
15 | * 输出
16 | * 第一行k-1个整数,每两个数之间用空格隔开,第i个数Ai表示应该在第Ai行和第Ai+1行之间切一刀。
17 | *
18 | * 第二行k-1个整数,每两个数之间用空格隔开,第i个数Bi表示应该在第Bi列和第Bi+1列之间切一刀。
19 | *
20 | * 如果有多种切法,输出字典序最小的那种。数据保证有解。输出的每一行的末尾不应有多余的空格。
21 | *
22 | *
23 | * 样例输入
24 | * 4 4 2
25 | * 1 4
26 | * 2 2
27 | * 3 1
28 | * 3 3
29 | * 样例输出
30 | * 2
31 | * 2
32 | *
33 | * Hint
34 | * 样例解释
35 | * 00|01
36 | * 01|00
37 | * --+--
38 | * 10|10
39 | * 00|00
40 | *
41 | * @author 刘壮飞
42 | * https://github.com/zfman.
43 | * https://blog.csdn.net/lzhuangfei.
44 | */
45 | public class Baidu2 {
46 | }
47 |
--------------------------------------------------------------------------------
/src/other/Baidu3.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | /**
4 | * B序(未完成)
5 | * 时间限制:C/C++语言 1000MS;其他语言 3000MS
6 | * 内存限制:C/C++语言 65536KB;其他语言 589824KB
7 | * 题目描述:
8 | * 你有1-n共n个数字可以使用,每个数字的使用次数无限制,显然共有n^n个不同的长度为n的序列。其中所有不上升序列和不下降序列统称为B序,给定n,问长度同样为n的b序有多少个,因为结果比较大,请输出答案对1000000007取模之后的结果。
9 | *
10 | * 不上升序列:从序列第二个数字开始,均小于等于前一个数字。
11 | *
12 | * 不下降序列:从序列第二个数字开始,均大于等于前一个数字。
13 | *
14 | * 输入
15 | * 输入仅包含一个正整数n(1<=n<=10^5)。
16 | *
17 | * 输出描述
18 | *
19 | * 输出
20 | * 输出仅包含一个正整数,表示答案对1000000007取模的结果。
21 | *
22 | *
23 | * 样例输入
24 | * 2
25 | * 样例输出
26 | * 4
27 | *
28 | * Hint
29 | * 输入样例2
30 | * 3
31 | * 输出样例2
32 | * 17
33 | *
34 | * @author 刘壮飞
35 | * https://github.com/zfman.
36 | * https://blog.csdn.net/lzhuangfei.
37 | */
38 | public class Baidu3 {
39 | }
40 |
--------------------------------------------------------------------------------
/src/other/GraphTest.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | import leetcode.common.AMGraph;
4 | import leetcode.common.GraphUtils;
5 | import utils.ArrayUtils;
6 |
7 | import java.util.LinkedList;
8 | import java.util.Queue;
9 | import java.util.Scanner;
10 | import java.util.Stack;
11 |
12 | /**
13 | * @author 刘壮飞
14 | * https://github.com/zfman.
15 | * https://blog.csdn.net/lzhuangfei.
16 | */
17 | public class GraphTest {
18 | public static void main(String[] args) {
19 | AMGraph graph=GraphUtils.cin();
20 | boolean[] visited=new boolean[graph.vexNum+1];
21 | // dfs(graph,1,visited);
22 | // GraphUtils.print(graph);
23 |
24 | Queue queue=new LinkedList<>();
25 | bfs(graph,5,visited,queue);
26 | }
27 |
28 | /**
29 | * 连通图的深度优先遍历,对于非连通图,
30 | * 应该依次将顶点作为遍历的起始点
31 | *
32 | * @param graph 图
33 | * @param v 访问的顶点
34 | * @param visited 访问标志数组
35 | */
36 | public static void dfs(AMGraph graph, int v, boolean[] visited){
37 | System.out.println("visited::"+v);
38 | visited[v]=true;
39 | for(int i=1;i<=graph.vexNum;i++){
40 | if(graph.arcs[v][i]!=0&&!visited[i]) dfs(graph,i,visited);
41 | }
42 | }
43 |
44 | /**
45 | * 图的广度优先遍历
46 | *
47 | * @param graph 图
48 | * @param v 起始顶点
49 | * @param visited 访问标志数组
50 | * @param queue 队列
51 | */
52 | public static void bfs(AMGraph graph, int v, boolean[] visited,Queue queue){
53 | if(!visited[v]){
54 | visited[v]=true;
55 | System.out.println("visited::"+v);
56 | queue.offer(v);
57 | }
58 | while (!queue.isEmpty()){
59 | Integer pop=queue.poll();
60 | if(!visited[pop]){
61 | visited[pop]=true;
62 | System.out.println("visited::"+pop);
63 | }
64 | for(int i=1;i<=graph.vexNum;i++){
65 | if(graph.arcs[pop][i]!=0&&!visited[i]){
66 | queue.offer(i);
67 | }
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/other/Mogujie1.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 |
4 | import java.util.Scanner;
5 |
6 | /**
7 | * 蘑菇街-网格路径数(未完成)
8 | * 给定网格x*y,求解从左上角到右下角的路径数,每次只能向右或向下移动一格
9 | *
10 | * input:
11 | * 3 2
12 | *
13 | * output:
14 | * 10
15 | *
16 | * @author 刘壮飞
17 | * https://github.com/zfman.
18 | * https://blog.csdn.net/lzhuangfei.
19 | */
20 | public class Mogujie1 {
21 | public static void main(String[] args){
22 | Scanner scanner=new Scanner(System.in);
23 | int x=scanner.nextInt();
24 | int y=scanner.nextInt();
25 |
26 | int X=x+y-2;
27 | int r=x-1;
28 | double ret=1.0;
29 | for(int i=1;i<=x-1;i++){
30 | ret=ret*(X-r+i)/i;
31 | }
32 | System.out.println((int)ret);
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/other/Mogujie2.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | import utils.ArrayUtils;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Collections;
7 | import java.util.List;
8 | import java.util.Scanner;
9 |
10 | /**
11 | * 蘑菇街 - 分词(未完成)
12 | *
13 | * 第一行是一个字符串,第二行是字典逗号分隔每一个词,
14 | * 输出分词结果,有多种分词结果使用逗号分隔
15 | *
16 | * input:
17 | * catsanddog
18 | * cat,cats,and,sand,dog
19 | *
20 | * output:
21 | * [cats and dog,cat sand dog]
22 | *
23 | * @author 刘壮飞
24 | * https://github.com/zfman.
25 | * https://blog.csdn.net/lzhuangfei.
26 | */
27 | public class Mogujie2 {
28 | public static void main(String[] args){
29 | Scanner scanner=new Scanner(System.in);
30 | String ling1=scanner.nextLine();
31 | String line2=scanner.nextLine();
32 | String[] arr=line2.substring(7,line2.length()-1).split(",");
33 | List list=new ArrayList<>();
34 | for(int i=0;i1&&arr[1].equals(name)){
29 | is=true;
30 | System.out.println(content);
31 | }else is=false;
32 | }else{
33 | if(is) System.out.println(content);
34 | }
35 | }
36 | }
37 | }
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/other/ShenCe1.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * 把陀峰命名改为下划线命名
7 | * 输入:
8 | * SensorsData
9 | *
10 | * 输出:
11 | * sensors_data
12 | */
13 | public class ShenCe1 {
14 | public static void main(String[] args){
15 | Scanner scanner=new Scanner(System.in);
16 | String str=scanner.nextLine();
17 | String ret="";
18 | for(int i=0;i='A'&&ch<='Z')){
21 | char tmp=(char)((int)ch+32);
22 | if(i==0){
23 | ret+=tmp;
24 | }else{
25 | ret+="_"+tmp;
26 | }
27 | }else{
28 | ret+=ch;
29 | }
30 | }
31 | System.out.println(ret);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/other/ShenCe2.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 | import java.util.Scanner;
7 |
8 | /**
9 | * 神策数据
10 | * 输入两行,第一行为时钟,第二行是经过的时间,输入时钟显示的结果
11 | *
12 | * 输入:
13 | * 10:00:00
14 | * 00:11:12
15 | *
16 | * 输出:
17 | * 10:11:12
18 | *
19 | */
20 | public class ShenCe2 {
21 | public static void main(String[] args){
22 | Scanner scanner=new Scanner(System.in);
23 | String line1=scanner.nextLine();
24 | String line2=scanner.nextLine();
25 | SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
26 | SimpleDateFormat sdf2=new SimpleDateFormat("HH:mm:ss");
27 | try {
28 | Date date1=sdf.parse("2018-09-21 "+line1);
29 | Date date2=sdf.parse("2018-09-21 "+line2);
30 | Date date3=sdf.parse("2018-09-21 00:00:00");
31 | Date date4=new Date(date1.getTime()+(date2.getTime()-date3.getTime()));
32 | String ret=sdf2.format(date4);
33 | System.out.println(ret);
34 | } catch (ParseException e) {
35 | e.printStackTrace();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/other/ShenCeInterview1.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | /**
4 | * 神策数据 面试手写算法题1 - 折半查找的实现
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class ShenCeInterview1 {
11 | public int find(int[] arr,int l,int r,int val){
12 | if(l>r) return -1;
13 | int middle=(l+r)/2;
14 | if(val>arr[middle]) return find(arr,middle+1,r,val);
15 | else if(valmax) max=arr[i];
21 | }
22 |
23 | // 下标保存数字
24 | // 元素值保存的是次数
25 | // java int[] 元素默认为0
26 | int[] b=new int[max+1];
27 | for(int i=0;i set=new HashSet<>();
19 | for(Integer val:arr){
20 | set.add(val);
21 | }
22 | int[] newArr=new int[set.size()];
23 | int i=0;
24 | for(Integer val:set){
25 | newArr[i++]=val;
26 | }
27 | for(int t=0;t list=new ArrayList<>();
40 | for(int i=0;imax) max=list.size();
48 | list.clear();
49 | break;
50 | }
51 | }
52 | if(list.size()>max) max=list.size();
53 | }
54 | return max;
55 | }
56 | /******************************结束写代码******************************/
57 |
58 |
59 | public static void main(String[] args){
60 | Scanner in = new Scanner(System.in);
61 | int res;
62 |
63 | String _s;
64 | try {
65 | _s = in.nextLine();
66 | } catch (Exception e) {
67 | _s = null;
68 | }
69 |
70 | res = lengthOfSubstring(_s);
71 | System.out.println(String.valueOf(res));
72 |
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/src/other/XunleiTest1.java:
--------------------------------------------------------------------------------
1 | package other;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * 求数列的和
7 | *
8 | * (编程题须知)(参考答案)
9 | *
10 | * 时间限制:C/C++语言 2000MS;其他语言 4000MS
11 | * 内存限制:C/C++语言 32768KB;其他语言 557056KB
12 | * 题目描述:
13 | * 数列的定义如下: 数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和。
14 | *
15 | * 输入
16 | * 输入数据有多组,每组占一行,由两个整数n(n<10000)和m(m<1000)组成,n和m的含义如前所述。
17 | *
18 | * 输出
19 | * 对于每组输入数据,输出该数列的和,每个测试实例占一行,要求精度保留2位小数。
20 | *
21 | *
22 | * 样例输入
23 | * 81 4
24 | * 2 2
25 | *
26 | * 样例输出
27 | * 94.73
28 | * 3.41
29 | *
30 | * @author 刘壮飞
31 | * https://github.com/zfman.
32 | * https://blog.csdn.net/lzhuangfei.
33 | */
34 | public class XunleiTest1 {
35 | public static void main(String[] args){
36 | Scanner scanner=new Scanner(System.in);
37 | while (scanner.hasNextInt()){
38 | int first=scanner.nextInt();
39 | int c=scanner.nextInt();
40 | double p=first;
41 | double s=p;
42 | for(int i=1;i generateParenthesis(int n){
33 | List ret=new ArrayList<>();
34 | dfs(n,0,0,"",ret);
35 | return ret;
36 | }
37 |
38 | /**
39 | * 深度优先
40 | *
41 | * 1.如果满足条件,将当前str保存,否则继续
42 | * 2.左括号小于n,继续添加左括号
43 | * 3.右括号小于n&左括号大于右括号,补充右括号
44 | *
45 | * @param n
46 | * @param l 左括号数量
47 | * @param r 右括号数量
48 | * @param str 本轮次的字符串
49 | * @param ret 保存所有结果
50 | */
51 | public void dfs(int n,int l,int r,String str,List ret){
52 | if(l>=n&&r>=n) {
53 | ret.add(str);
54 | return;
55 | }
56 | if(lr&&r r=new ZhaoShang2018_1().generateParenthesis(3);
66 | for (String s:r){
67 | System.out.println(s);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/pattern/chain/AbstractLogger.java:
--------------------------------------------------------------------------------
1 | package pattern.chain;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public abstract class AbstractLogger {
9 | public static final int LOG_ERROR=1;
10 | public static final int LOG_DEBUG=2;
11 | public static final int LOG_INFO=3;
12 | protected int level;
13 | protected AbstractLogger nextLogger;
14 |
15 | public abstract void write(String msg);
16 |
17 | public void logMessage(int level,String msg){
18 | if(this.level<=level){
19 | write(msg);
20 | }
21 | if(nextLogger!=null){
22 | nextLogger.logMessage(level,msg);
23 | }
24 | }
25 |
26 | public void setNextLogger(AbstractLogger nextLogger) {
27 | this.nextLogger = nextLogger;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/pattern/chain/Client.java:
--------------------------------------------------------------------------------
1 | package pattern.chain;
2 |
3 | /**
4 | * 职责链模式
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class Client {
11 | public static void main(String[] args){
12 | AbstractLogger errorLogger=new ErrorLogger(AbstractLogger.LOG_ERROR);
13 | AbstractLogger debugLogger=new FileLogger(AbstractLogger.LOG_DEBUG);
14 | AbstractLogger infoLogger=new ConsoleLogger(AbstractLogger.LOG_INFO);
15 |
16 | errorLogger.setNextLogger(debugLogger);
17 | debugLogger.setNextLogger(infoLogger);
18 |
19 | errorLogger.logMessage(AbstractLogger.LOG_INFO,"hello info");
20 | errorLogger.logMessage(AbstractLogger.LOG_DEBUG,"hello debug");
21 | errorLogger.logMessage(AbstractLogger.LOG_ERROR,"hello error");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/pattern/chain/ConsoleLogger.java:
--------------------------------------------------------------------------------
1 | package pattern.chain;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class ConsoleLogger extends AbstractLogger {
9 | public ConsoleLogger(int level){
10 | this.level=level;
11 | }
12 | @Override
13 | public void write(String msg) {
14 | System.out.println("ConsoleLogger::"+msg);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/pattern/chain/ErrorLogger.java:
--------------------------------------------------------------------------------
1 | package pattern.chain;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class ErrorLogger extends AbstractLogger {
9 | public ErrorLogger(int level){
10 | this.level=level;
11 | }
12 | @Override
13 | public void write(String msg) {
14 | System.out.println("ErrorLogger::"+msg);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/pattern/chain/FileLogger.java:
--------------------------------------------------------------------------------
1 | package pattern.chain;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class FileLogger extends AbstractLogger {
9 |
10 | public FileLogger(int level){
11 | this.level=level;
12 | }
13 | @Override
14 | public void write(String msg) {
15 | System.out.println("FileLogger::"+msg);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/pattern/command/BuyStock.java:
--------------------------------------------------------------------------------
1 | package pattern.command;
2 |
3 | /**
4 | * buyStock 命令
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class BuyStock implements Order {
11 | Stock stock;
12 | public BuyStock(Stock stock){
13 | this.stock=stock;
14 | }
15 | @Override
16 | public void execute() {
17 | stock.buy();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/pattern/command/Client.java:
--------------------------------------------------------------------------------
1 | package pattern.command;
2 |
3 | /**
4 | * 命令模式
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class Client {
11 | public static void main(String[] args){
12 | Stock stock=new Stock();
13 | BuyStock buyStock=new BuyStock(stock);
14 | SellStock sellStock=new SellStock(stock);
15 |
16 | Invoker invoker=new Invoker();
17 | invoker.takeOrder(buyStock);
18 | invoker.takeOrder(sellStock);
19 | invoker.placeOrders();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/pattern/command/Invoker.java:
--------------------------------------------------------------------------------
1 | package pattern.command;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 命令调用者
8 | * @author 刘壮飞
9 | * https://github.com/zfman.
10 | * https://blog.csdn.net/lzhuangfei.
11 | */
12 | public class Invoker {
13 | public List orders=new ArrayList<>();
14 |
15 | public void takeOrder(Order o){
16 | orders.add(o);
17 | }
18 |
19 | public void placeOrders(){
20 | for(Order o:orders){
21 | o.execute();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/pattern/command/Order.java:
--------------------------------------------------------------------------------
1 | package pattern.command;
2 |
3 | /**
4 | * 命令的抽象接口
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public interface Order {
11 | void execute();
12 | }
13 |
--------------------------------------------------------------------------------
/src/pattern/command/SellStock.java:
--------------------------------------------------------------------------------
1 | package pattern.command;
2 |
3 | /**
4 | * sellStock命令
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class SellStock implements Order{
11 | Stock stock;
12 | public SellStock(Stock stock){
13 | this.stock=stock;
14 | }
15 |
16 | @Override
17 | public void execute() {
18 | stock.sell();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/pattern/command/Stock.java:
--------------------------------------------------------------------------------
1 | package pattern.command;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class Stock {
9 | public String name="aa";
10 | public float quantity=4.0f;
11 |
12 | public void buy(){
13 | System.out.println("buy::"+name+","+quantity);
14 | }
15 |
16 | public void sell(){
17 | System.out.println("sell::"+name+","+quantity);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/pattern/iterator/Client.java:
--------------------------------------------------------------------------------
1 | package pattern.iterator;
2 |
3 | /**
4 | * 迭代器模式
5 | * @author 刘壮飞
6 | * https://github.com/zfman.
7 | * https://blog.csdn.net/lzhuangfei.
8 | */
9 | public class Client {
10 | public static void main(String[] args){
11 | NameRepository repository=new NameRepository();
12 | Iterator iterator=repository.iterator();
13 | while (iterator.hasNext()){
14 | System.out.println(iterator.next());
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/pattern/iterator/Container.java:
--------------------------------------------------------------------------------
1 | package pattern.iterator;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public interface Container {
9 | Iterator iterator();
10 | }
11 |
--------------------------------------------------------------------------------
/src/pattern/iterator/Iterator.java:
--------------------------------------------------------------------------------
1 | package pattern.iterator;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public interface Iterator {
9 | public boolean hasNext();
10 | public Object next();
11 | }
12 |
--------------------------------------------------------------------------------
/src/pattern/iterator/NameRepository.java:
--------------------------------------------------------------------------------
1 | package pattern.iterator;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class NameRepository implements Container {
9 |
10 | public String names[] = {"Robert" , "John" ,"Julie" , "Lora"};
11 |
12 | @Override
13 | public Iterator iterator() {
14 | return new NameIterator();
15 | }
16 |
17 | class NameIterator implements Iterator{
18 | int index;
19 | @Override
20 | public boolean hasNext() {
21 | if(index mementos=new ArrayList<>();
13 | public void add(Memento memento){
14 | mementos.add(memento);
15 | }
16 | public Memento get(int i){
17 | return mementos.get(i);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/pattern/memento/Client.java:
--------------------------------------------------------------------------------
1 | package pattern.memento;
2 |
3 | /**
4 | * 备忘录模式
5 | * @author 刘壮飞
6 | * https://github.com/zfman.
7 | * https://blog.csdn.net/lzhuangfei.
8 | */
9 | public class Client {
10 | public static void main(String[] args){
11 | Originator originator=new Originator();
12 | originator.setState("State 1");
13 | System.out.println(originator.getState());
14 |
15 | CareTaker taker=new CareTaker();
16 | taker.add(originator.saveState());
17 |
18 | originator.setState("State 2");
19 | taker.add(originator.saveState());
20 | System.out.println(originator.getState());
21 |
22 | originator.restoreFromState(taker.get(0));
23 | System.out.println(originator.getState());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/pattern/memento/Memento.java:
--------------------------------------------------------------------------------
1 | package pattern.memento;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class Memento {
9 | private String state;
10 |
11 | public Memento(String state){
12 | this.state=state;
13 | }
14 |
15 | public String getState() {
16 | return state;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/pattern/memento/Originator.java:
--------------------------------------------------------------------------------
1 | package pattern.memento;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class Originator {
9 | String state;
10 |
11 | public void setState(String state) {
12 | this.state = state;
13 | }
14 |
15 | public String getState() {
16 | return state;
17 | }
18 |
19 | public Memento saveState(){
20 | return new Memento(state);
21 | }
22 |
23 | public void restoreFromState(Memento memento){
24 | this.state=memento.getState();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/pattern/observer/Client.java:
--------------------------------------------------------------------------------
1 | package pattern.observer;
2 |
3 | /**
4 | * 观察者模式
5 | * @author 刘壮飞
6 | * https://github.com/zfman.
7 | * https://blog.csdn.net/lzhuangfei.
8 | */
9 | public class Client {
10 | public static void main(String[] args){
11 | Subject subject=new Subject();
12 | new Observer1(subject);
13 | new Observer2(subject);
14 |
15 | subject.setState("New State");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/pattern/observer/Observer.java:
--------------------------------------------------------------------------------
1 | package pattern.observer;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public abstract class Observer {
9 | protected Subject subject;
10 | abstract void update();
11 | }
12 |
--------------------------------------------------------------------------------
/src/pattern/observer/Observer1.java:
--------------------------------------------------------------------------------
1 | package pattern.observer;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class Observer1 extends Observer {
9 | public Observer1(Subject subject){
10 | this.subject=subject;
11 | this.subject.attach(this);
12 | }
13 | @Override
14 | public void update() {
15 | System.out.println("Observer1::update");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/pattern/observer/Observer2.java:
--------------------------------------------------------------------------------
1 | package pattern.observer;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class Observer2 extends Observer {
9 | public Observer2(Subject subject){
10 | this.subject=subject;
11 | this.subject.attach(this);
12 | }
13 | @Override
14 | public void update() {
15 | System.out.println("Observer2::update");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/pattern/observer/Subject.java:
--------------------------------------------------------------------------------
1 | package pattern.observer;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author 刘壮飞
8 | * https://github.com/zfman.
9 | * https://blog.csdn.net/lzhuangfei.
10 | */
11 | public class Subject {
12 | List observers=new ArrayList<>();
13 | String state;
14 |
15 | public void setState(String state) {
16 | this.state = state;
17 | onNotify();
18 | }
19 |
20 | public String getState() {
21 | return state;
22 | }
23 |
24 | public void attach(Observer observer){
25 | observers.add(observer);
26 | }
27 |
28 | public void onNotify(){
29 | for(Observer observer:observers){
30 | observer.update();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/sort/ArrayUtils.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class ArrayUtils {
9 | public static void printArray(T[] a){
10 | if(a==null) return;
11 | for(int i=0;i void printArray(T[] a,int start){
18 | if(a==null) return;
19 | for(int i=start;i> extends Sort {
14 | @Override
15 | public void sort(T[] nums) {
16 | int n=nums.length;
17 | for(int i=0;i sort=new Buddle<>();
31 | sort.sort(arr);
32 | ArrayUtils.printArray(arr);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/sort/Buddle2.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * 冒泡排序的改进
5 | *
6 | * 通过从左到右不断交换相邻逆序的相邻元素,
7 | * 在一轮的交换之后,可以让未排序的元素上浮到右侧。
8 | *
9 | * 在一轮循环中,如果没有发生交换,就说明数组已经是有序的,此时可以直接退出。
10 | *
11 | * @author 刘壮飞
12 | * https://github.com/zfman.
13 | * https://blog.csdn.net/lzhuangfei.
14 | */
15 | public class Buddle2> extends Sort {
16 | @Override
17 | public void sort(T[] nums) {
18 | int n=nums.length;
19 | boolean hasSort=false;
20 | for(int i=0;i sort=new Buddle2<>();
36 | sort.sort(arr);
37 | ArrayUtils.printArray(arr);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/sort/DownToUpMergeSort.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * 自底向上归并排序
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class DownToUpMergeSort> extends MergeSort {
11 |
12 | /**
13 | * 先归并那些微型数组,然后成对归并得到的微型数组。
14 | *
15 | * @param nums
16 | */
17 | @Override
18 | public void sort(T[] nums) {
19 | int n = nums.length;
20 | tmp = (T[]) new Comparable[n];
21 | for (int i = 1; i < n; i += i)
22 | for (int j = 0; j < n - i; j += i + i)
23 | merge(nums, j, j + i - 1, Math.min(j + i + i - 1, n - 1));
24 | }
25 |
26 | public static void main(String[] args) {
27 | Integer[] arr = {
28 | 5, 1, 8, 7, 10, 6, 9, 5, 20, 3, 0
29 | };
30 | Sort sort = new DownToUpMergeSort<>();
31 | sort.sort(arr);
32 | ArrayUtils.printArray(arr);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/sort/Heap.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public class Heap> {
9 |
10 | private T[] heap;
11 | private int n=0;
12 |
13 | public Heap(int maxNum){
14 | n=maxNum;
15 | }
16 |
17 | public boolean isEmpty(){
18 | return n==0;
19 | }
20 |
21 | protected boolean less(int i,int j){
22 | return heap[i].compareTo(heap[j])<0;
23 | }
24 |
25 | protected void swap(int i,int j){
26 | T t=heap[i];
27 | heap[i]=heap[j];
28 | heap[j]=t;
29 | }
30 |
31 | /**
32 | * 上浮
33 | * @param k
34 | */
35 | protected void swim(int k){
36 | while (k>1&&less(k/2,k)){
37 | swap(k/2,k);
38 | k=k/2;
39 | }
40 | }
41 |
42 | /**
43 | * 下沉
44 | * @param k
45 | */
46 | protected void sink(int k){
47 | while (2*k<=n){
48 | int j=2*k;
49 | if(j> extends Sort{
14 | @Override
15 | public void sort(T[] nums) {
16 | int n=nums.length-1;
17 | for(int k=n/2;k>=1;k--){
18 | sink(nums,k,n);
19 | }
20 | while(n>1){
21 | swap(nums,1,n--);
22 | sink(nums,1,n);
23 | }
24 | }
25 |
26 | public void sink(T[] nums,int k,int n){
27 | while(2*k<=n){
28 | int j=2*k;
29 | if(j sort=new HeapSort<>();
47 | sort.sort(arr);
48 | ArrayUtils.printArray(arr,1);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/sort/Insertion.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * 插入排序
5 | *
6 | * 插入排序从左到右进行,每次都将当前元素插入到左侧已经排序的数组中,
7 | * 使得插入之后左部数组依然有序。
8 | * 第 j 元素是通过不断向左比较并交换来实现插入过程:
9 | * 当第 j 元素小于第 j - 1 元素,就将它们的位置交换,
10 | * 然后令 j 指针向左移动一个位置,不断进行以上操作。
11 | *
12 | * 插入排序的复杂度取决于数组的初始顺序,如果数组已经部分有序了,逆序较少,那么插入排序会很快。
13 | *
14 | * 平均情况下插入排序需要 ~N2/4 比较以及 ~N2/4 次交换;
15 | * 最坏的情况下需要 ~N2/2 比较以及 ~N2/2 次交换,最坏的情况是数组是倒序的;
16 | * 最好的情况下需要 N-1 次比较和 0 次交换,最好的情况就是数组已经有序了。
17 | *
18 | * @author 刘壮飞
19 | * https://github.com/zfman.
20 | * https://blog.csdn.net/lzhuangfei.
21 | */
22 | public class Insertion> extends Sort {
23 | @Override
24 | public void sort(T[] nums) {
25 | int n=nums.length;
26 | for(int i=1;i0&&less(nums[j],nums[j-1]);j--){
28 | swap(nums,j,j-1);
29 | }
30 | }
31 | }
32 |
33 | public static void main(String[] args){
34 | Integer[] arr={
35 | 5,1,8,7,10,6,9,5,20,3,0
36 | };
37 | Sort sort=new Insertion<>();
38 | sort.sort(arr);
39 | ArrayUtils.printArray(arr);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/sort/MergeSort.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * 归并排序的思想是将数组分成两部分,分别进行排序,然后归并起来。
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public abstract class MergeSort> extends Sort {
11 |
12 | protected T[] tmp;
13 |
14 | protected void merge(T[] nums, int l, int m, int h) {
15 | //i:待归并的前者的位置,j:待归并的后者的位置
16 | int i = l, j = m + 1;
17 | for (int k = l; k <= h; k++) {
18 | tmp[k] = nums[k];
19 | }
20 |
21 | //两个子序列合并
22 | int v=l;
23 | while(i<=m&&j<=h){
24 | if(tmp[i].compareTo(tmp[j])<=0) nums[v++]=tmp[i++];
25 | else nums[v++]=tmp[j++];
26 | }
27 | if(m>i){
28 | for(;j<=h;j++) nums[v++]=tmp[j];
29 | }
30 | if(j>h){
31 | for(;i<=m;i++) nums[v++]=tmp[i];
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/sort/QuickSort.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collections;
5 | import java.util.List;
6 |
7 | /**
8 | * 快速排序
9 | *
10 | * 快速排序通过一个切分元素将数组分为两个子数组,左子数组小于等于切分元素,
11 | * 右子数组大于等于切分元素,将这两个子数组排序也就将整个数组排序了。
12 | *
13 | * 性能分析
14 | *
15 | * 快速排序是原地排序,不需要辅助数组,但是递归调用需要辅助栈。
16 | *
17 | * 快速排序最好的情况下是每次都正好能将数组对半分,这样递归调用次数才是最少的。
18 | * 这种情况下比较次数为 CN=2CN/2+N,复杂度为 O(NlogN)。
19 | *
20 | * 最坏的情况下,第一次从最小的元素切分,第二次从第二小的元素切分,如此这般。
21 | * 因此最坏的情况下需要比较 N2/2。为了防止数组最开始就是有序的,在进行快速排序时需要随机打乱数组。
22 | *
23 | * 算法改进
24 | *
25 | * (一)切换到插入排序
26 | *
27 | * 因为快速排序在小数组中也会递归调用自己,对于小数组,插入排序比快速排序的性能更好,
28 | * 因此在小数组中可以切换到插入排序。
29 | *
30 | * (二)三数取中
31 | *
32 | * 最好的情况下是每次都能取数组的中位数作为切分元素,但是计算中位数的代价很高。
33 | * 人们发现取 3 个元素并将大小居中的元素作为切分元素的效果最好。
34 | *
35 | * (三)三向切分
36 | *
37 | * 对于有大量重复元素的数组,可以将数组切分为三部分,分别对应小于、等于和大于切分元素。
38 | *
39 | * 三向切分快速排序对于只有若干不同主键的随机数组可以在线性时间内完成排序。
40 | *
41 | * @author 刘壮飞
42 | * https://github.com/zfman.
43 | * https://blog.csdn.net/lzhuangfei.
44 | */
45 | public class QuickSort> extends Sort {
46 | @Override
47 | public void sort(T[] nums) {
48 | shuffle(nums);
49 | sort(nums,0,nums.length-1);
50 | }
51 |
52 | public void sort(T[] nums,int l,int h){
53 | if(l>=h) return;
54 | int j=partition(nums,l,h);
55 | sort(nums,l,j-1);
56 | sort(nums,j+1,h);
57 | }
58 |
59 | /**
60 | * 切分
61 | * @param nums
62 | * @param l
63 | * @param h
64 | * @return
65 | */
66 | public int partition(T[] nums,int l,int h){
67 | int i=l,j=h+1;
68 | T v=nums[l];
69 | while(true){
70 | while(j!=l&&less(v,nums[--j]));
71 | while(i!=h&&less(nums[++i],v));
72 | if(i>=j) break;
73 | swap(nums,i,j);
74 | }
75 | swap(nums,l,j);
76 | return j;
77 | }
78 |
79 | /**
80 | * 打乱顺序
81 | * @param nums
82 | */
83 | public void shuffle(T[] nums){
84 | List list=Arrays.asList(nums);
85 | Collections.shuffle(list);
86 | list.toArray(nums);
87 | }
88 |
89 | public static void main(String[] args){
90 | Integer[] arr={
91 | 5,1,8,7,10,6,9,5,20,3,0
92 | };
93 | Sort sort=new QuickSort<>();
94 | sort.sort(arr);
95 | ArrayUtils.printArray(arr);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/sort/Selection.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * 选择排序
5 | *
6 | * 选择出数组中的最小元素,将它与数组的第一个元素交换位置。
7 | * 再从剩下的元素中选择出最小的元素,将它与数组的第二个元素交换位置。
8 | * 不断进行这样的操作,直到将整个数组排序。
9 | *
10 | * @author 刘壮飞
11 | * https://github.com/zfman.
12 | * https://blog.csdn.net/lzhuangfei.
13 | */
14 | public class Selection> extends Sort{
15 | @Override
16 | public void sort(T[] nums) {
17 | int n=nums.length;
18 | for(int i=0;i sort=new Selection<>();
32 | sort.sort(arr);
33 | ArrayUtils.printArray(arr);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/sort/Shell.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * 希尔排序
5 | *
6 | * 先将整个待排记录序列分割成若干子序列,分别进行直接插入排序,
7 | * 待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序
8 | *
9 | * 对于大规模的数组,插入排序很慢,因为它只能交换相邻的元素,每次只能将逆序数量减少 1。
10 | * 希尔排序的出现就是为了改进插入排序的这种局限性,它通过交换不相邻的元素,每次可以将逆序数量减少大于 1。
11 | * 希尔排序使用插入排序对间隔 h 的序列进行排序。通过不断减小 h,最后令 h=1,就可以使得整个数组是有序的。
12 | *
13 | *
14 | *
15 | * @author 刘壮飞
16 | * https://github.com/zfman.
17 | * https://blog.csdn.net/lzhuangfei.
18 | */
19 | public class Shell> extends Sort {
20 | @Override
21 | public void sort(T[] nums) {
22 | int n=nums.length;
23 | int step=1;
24 | while (step=1){
27 | for(int i=step;i=step&&less(nums[j],nums[j-step]);j-=step){
29 | swap(nums,j,j-step);
30 | }
31 | }
32 | step=step/3;
33 | }
34 |
35 | }
36 |
37 | public static void main(String[] args){
38 | Integer[] arr={
39 | 5,1,8,7,10,6,9,5,20,3,0
40 | };
41 | Sort sort=new Shell<>();
42 | sort.sort(arr);
43 | ArrayUtils.printArray(arr);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/sort/Sort.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * @author 刘壮飞
5 | * https://github.com/zfman.
6 | * https://blog.csdn.net/lzhuangfei.
7 | */
8 | public abstract class Sort> {
9 | public abstract void sort(T[] nums);
10 |
11 | public boolean less(T v,T w){
12 | return v.compareTo(w)<0;
13 | }
14 |
15 | public void swap(T[] a,int i,int j){
16 | T t=a[i];
17 | a[i]=a[j];
18 | a[j]=t;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/sort/ThreeWayQuickSort.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * 三向切分快速排序
5 | * 对于有大量重复元素的数组,可以将数组切分为三部分,分别对应小于、等于和大于切分元素。
6 | *
7 | * 三向切分快速排序对于只有若干不同主键的随机数组可以在线性时间内完成排序。
8 | *
9 | * @author 刘壮飞
10 | * https://github.com/zfman.
11 | * https://blog.csdn.net/lzhuangfei.
12 | */
13 | public class ThreeWayQuickSort> extends QuickSort {
14 | @Override
15 | public void sort(T[] nums, int l, int h) {
16 | if(l>=h) return;
17 | int lt=l,i=l+1,gt=h;
18 | T v=nums[l];
19 | System.out.println(v);
20 | while (i<=gt){
21 | int compare=nums[i].compareTo(v);
22 | if(compare<0){
23 | swap(nums,lt++,i++);
24 | }else if(compare>0){
25 | swap(nums,i,gt--);
26 | }else {
27 | i++;
28 | }
29 | }
30 | sort(nums,l,lt-1);
31 | sort(nums,gt+1,h);
32 | }
33 |
34 | public static void main(String[] args){
35 | Integer[] arr={
36 | 5,1,8,1,3,3,3,3,5,5,8,8,8
37 | };
38 | ArrayUtils.printArray(arr);
39 | Sort sort=new ThreeWayQuickSort<>();
40 | sort.sort(arr);
41 | ArrayUtils.printArray(arr);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/sort/UpToDownMergeSort.java:
--------------------------------------------------------------------------------
1 | package sort;
2 |
3 | /**
4 | * 自顶向下归并排序
5 | *
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class UpToDownMergeSort> extends MergeSort {
11 |
12 | /**
13 | * 因为每次都将问题对半分成两个子问题,
14 | * 而这种对半分的算法复杂度一般为 O(NlogN),
15 | * 因此该归并排序方法的时间复杂度也为 O(NlogN)。
16 | *
17 | * @param nums
18 | */
19 | @Override
20 | public void sort(T[] nums) {
21 | tmp= (T[]) new Comparable[nums.length];
22 | sort(nums,0,nums.length-1);
23 | }
24 |
25 | public void sort(T[] nums,int l,int h) {
26 | if(l>=h) return;
27 | int mid=l+(h-l)/2;
28 | sort(nums,l,mid);
29 | sort(nums,mid+1,h);
30 | merge(nums,l,mid,h);
31 | }
32 |
33 | public static void main(String[] args){
34 | Integer[] arr={
35 | 5,1,8,7,10,6,9,5,20,3,0
36 | };
37 | Sort sort=new UpToDownMergeSort<>();
38 | sort.sort(arr);
39 | ArrayUtils.printArray(arr);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/sort2/BuddleSort.java:
--------------------------------------------------------------------------------
1 | package sort2;
2 |
3 | import utils.ArrayUtils;
4 |
5 | /**
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class BuddleSort {
11 | public static void main(String[] args) {
12 | int[] m = {
13 | 3, 1, 5, 8, 4, 6, 9, 2, 4, 0
14 | };
15 |
16 | int n = m.length;
17 | for (int i = 0; i < n-1; i++) {
18 | for(int j=0;jm[j+1]){
20 | int tmp=m[j];
21 | m[j]=m[j+1];
22 | m[j+1]=tmp;
23 | }
24 | }
25 | }
26 |
27 | ArrayUtils.printArray(m);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/sort2/Insertion.java:
--------------------------------------------------------------------------------
1 | package sort2;
2 |
3 | import utils.ArrayUtils;
4 |
5 | /**
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class Insertion {
11 | public static void main(String[] args) {
12 | int[] m = {
13 | 3, 1, 5, 8, 4, 6, 9, 2, 4, 0
14 | };
15 |
16 | int n = m.length;
17 | for (int i = 1; i < n; i++) {
18 | for(int j=i;j>0&&m[j]=r) return;
15 | int j=partition(nums,l,r);
16 | sort(nums,l,j-1);
17 | sort(nums,j+1,r);
18 | }
19 |
20 | public int partition(int[] nums,int l,int r){
21 | int i=l;
22 | int j=r+1;
23 | int val=nums[l];
24 | while(true){
25 | while(j!=l&&nums[--j]>val);
26 | while(i!=r&&nums[++i]=j) break;
28 | swap(nums,i,j);
29 | }
30 | swap(nums,l,j);
31 | return j;
32 | }
33 |
34 | public void swap(int[] nums,int i,int j){
35 | int tmp=nums[i];
36 | nums[i]=nums[j];
37 | nums[j]=tmp;
38 | }
39 |
40 | public static void main(String[] args){
41 | int[] arr={
42 | 5,1,8,7,10,6,9,5,20,3,0
43 | };
44 | new QuickSort().sort(arr);
45 | ArrayUtils.printArray(arr);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/sort2/Selection.java:
--------------------------------------------------------------------------------
1 | package sort2;
2 |
3 | import utils.ArrayUtils;
4 |
5 | /**
6 | * @author 刘壮飞
7 | * https://github.com/zfman.
8 | * https://blog.csdn.net/lzhuangfei.
9 | */
10 | public class Selection {
11 | public static void main(String[] args) {
12 | int[] m = {
13 | 3, 1, 5, 8, 4, 6, 9, 2, 4, 0
14 | };
15 |
16 | int n = m.length;
17 | for (int i = 0; i < n; i++) {
18 | int min=i;
19 | for(int j=i+1;j=0;i--){
31 | if(index%2==0) v1+=a[i];
32 | else v2+=a[i];
33 | index++;
34 | }
35 | return v1-v2;
36 | }
37 |
38 | public static void main(String[] args){
39 | Scanner in = new Scanner(System.in);
40 | int n=in.nextInt();
41 | int[] a=new int[n];
42 | for(int i=0;i=1;i--){
29 | int other=m-i;//剩余块数
30 | int a=i;//当日吃的块数
31 | int j=n-1;//剩余天数
32 | for(;j>=1;j--){
33 | //能够满足的话就不需要继续遍历了
34 | if(a==1&&other>=j) {
35 | j=-1;
36 | break;
37 | }
38 | //不满足的话直接停止本轮遍历
39 | if(a==1&&otherm){
47 | return false;
48 | }
49 | if(n!=0&&m<0){
50 | return false;
51 | }else if(n!=0&&m>=0) {
52 | return isEnough ((int)Math.ceil (mid/2.0),--n,m-mid);
53 | }else {
54 | return true;
55 | }
56 | }
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/tencent/Main6.java:
--------------------------------------------------------------------------------
1 | package tencent;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * 求解一个数是否是和谐数:n的各个位之和能够被n整除,那么这个数是和谐数
7 | *
8 | * @author 刘壮飞
9 | * https://github.com/zfman.
10 | * https://blog.csdn.net/lzhuangfei.
11 | */
12 | public class Main6 {
13 | public static void main(String[] args){
14 | Scanner scanner=new Scanner(System.in);
15 | int n=scanner.nextInt();
16 | for(int i=0;i