0%

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.demo.s62;

/**
* 不同路径
* 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
*
* 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
*
* 问总共有多少条不同的路径?
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/unique-paths
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {

public int uniquePaths(int m, int n) {
//新建dp二维数组,记录每步状态
int[][] f = new int[m][n];
//初始化边界情况
for (int i = 0; i < m; ++i) {
f[i][0] = 1;
}
for (int j = 0; j < n; ++j) {
f[0][j] = 1;
}
//遍历行列,补全其他状态
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
//动态转移方程
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
return f[m - 1][n - 1];
}

}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.demo.s61;

/**
* 旋转链表
* 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
*/

class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public class Solution {
public ListNode rotateRight(ListNode head, int k) {
if(head == null) {
return null;
}
ListNode cur = head;
int n = 1;
//计算链表长度
while(cur.next != null) {
cur = cur.next;
n++;
}
//计算断开的位置
int y = n - k % n;
//特殊情况也就是链表不变的情况
if(y == n) {
return head;
}
//尾部连接到链表头
cur.next = head;
while(y -- > 0) {
cur = cur.next;
}
//按照计算的断开位置断开链表
head = cur.next;
cur.next = null;
return head;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.demo.s60;

import java.util.Arrays;

/**
* 排列序列
* 给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。
*
* 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
*
* "123"
* "132"
* "213"
* "231"
* "312"
* "321"
* 给定 n 和 k,返回第 k 个排列。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/permutation-sequence
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public String getPermutation(int n, int k) {
int[] factorial = new int[n];
factorial[0] = 1;
for (int i = 1; i < n; ++i) {
factorial[i] = factorial[i - 1] * i;
}

--k;
StringBuffer ans = new StringBuffer();
int[] valid = new int[n + 1];
Arrays.fill(valid, 1);
for (int i = 1; i <= n; ++i) {
int order = k / factorial[n - i] + 1;
for (int j = 1; j <= n; ++j) {
order -= valid[j];
if (order == 0) {
ans.append(j);
valid[j] = 0;
break;
}
}
k %= factorial[n - i];
}
return ans.toString();
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.demo.s6;

/**
* Z 字形变换
* 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
*
* 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/zigzag-conversion
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public String convert(String s, int numRows) {

if (numRows == 1) return s;

StringBuilder ret = new StringBuilder();
int n = s.length();
int cycleLen = 2 * numRows - 2;

for (int i = 0; i < numRows; i++) {
for (int j = 0; j + i < n; j += cycleLen) {
ret.append(s.charAt(j + i));
if (i != 0 && i != numRows - 1 && j + cycleLen - i < n)
ret.append(s.charAt(j + cycleLen - i));
}
}
return ret.toString();

}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.demo.s59;

/**
* 螺旋矩阵 II
* 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
*/
public class Solution {
public int[][] generateMatrix(int n) {
int maxNum = n * n;
int curNum = 1;
//返回值数组
int[][] matrix = new int[n][n];
int row = 0, column = 0;
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 右下左上
int directionIndex = 0;
while (curNum <= maxNum) {
matrix[row][column] = curNum;
curNum++;
//行
int nextRow = row + directions[directionIndex][0],
//列
nextColumn = column + directions[directionIndex][1];
//行列边界判断,需要调整方向
if (nextRow < 0 || nextRow >= n || nextColumn < 0 || nextColumn >= n || matrix[nextRow][nextColumn] != 0) {
// 顺时针旋转至下一个方向
directionIndex = (directionIndex + 1) % 4;
}
row = row + directions[directionIndex][0];
column = column + directions[directionIndex][1];
}
return matrix;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.demo.s58;

/**
* 最后一个单词的长度
* 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
*
* 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/length-of-last-word
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public int lengthOfLastWord(String s) {
int end = s.length() - 1;
while(end >= 0 && s.charAt(end) == ' ') end--;
if(end < 0) return 0;
int start = end;
while(start >= 0 && s.charAt(start) != ' ') start--;
return end - start;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.demo.s57;

import java.util.ArrayList;
import java.util.List;

/**
* 插入区间
* 给你一个 无重叠的 ,按照区间起始端点排序的区间列表。
*
* 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。
*
*
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/insert-interval
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
int left = newInterval[0];
int right = newInterval[1];
boolean placed = false;
List<int[]> ansList = new ArrayList<int[]>();
for (int[] interval : intervals) {
if (interval[0] > right) {
// 在插入区间的右侧且无交集
if (!placed) {
ansList.add(new int[]{left, right});
placed = true;
}
ansList.add(interval);
} else if (interval[1] < left) {
// 在插入区间的左侧且无交集
ansList.add(interval);
} else {
// 与插入区间有交集,计算它们的并集
left = Math.min(left, interval[0]);
right = Math.max(right, interval[1]);
}
}
if (!placed) {
ansList.add(new int[]{left, right});
}
int[][] ans = new int[ansList.size()][2];
for (int i = 0; i < ansList.size(); ++i) {
ans[i] = ansList.get(i);
}
return ans;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.demo.s56;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
* 合并区间
* 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
*
*  
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/merge-intervals
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public int[][] merge(int[][] intervals) {
if (intervals.length == 0) {
return new int[0][2];
}
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
List<int[]> merged = new ArrayList<int[]>();
for (int i = 0; i < intervals.length; ++i) {
int L = intervals[i][0], R = intervals[i][1];
if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) {
merged.add(new int[]{L, R});
} else {
merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R);
}
}
return merged.toArray(new int[merged.size()][]);
}

}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.demo.s55;

/**
* 跳跃游戏
* 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
*
* 数组中的每个元素代表你在该位置可以跳跃的最大长度。
*
* 判断你是否能够到达最后一个下标。
*/
public class Solution {
public boolean canJump(int[] nums) {
int n = nums.length;
int rightmost = 0;
for (int i = 0; i < n; ++i) {
if (i <= rightmost) {
rightmost = Math.max(rightmost, i + nums[i]);
if (rightmost >= n - 1) {
return true;
}
}
}
return false;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.demo.s543;

/**
* 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
*
*
*/

class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}


public class Solution {
int ans = 0;
public int diameterOfBinaryTree(TreeNode root) {
//遍历树
deep(root);
return ans;
}

public int deep(TreeNode root) {
//到叶子节点返回
if(root == null) {
return 0;
}
//左子树深度
int l = deep(root.left);
//右子树深度
int r = deep(root.right);
// 左右子树深度和
ans = Math.max(ans, l + r);
//加上根节点自身 就是直径
return Math.max(l, r) + 1;
}
}