Skip to content

Commit a9e3222

Browse files
committed
新增4题,累积17题
1 parent d807528 commit a9e3222

File tree

5 files changed

+232
-1
lines changed

5 files changed

+232
-1
lines changed

src/com/cjl/common/ListNode.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
public class ListNode {
55
public int val;
66
public ListNode next;
7+
public ListNode() { }
78
public ListNode(int x) {
8-
val = x;
9+
this.val = x;
10+
}
11+
public ListNode(int x, ListNode next) {
12+
this.val = x;
13+
this.next = next;
914
}
1015
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.cjl.leetcode;
2+
3+
import com.cjl.common.ListNode;
4+
5+
import java.util.Deque;
6+
7+
/*
8+
143. 重排链表
9+
问题描述:
10+
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
11+
L0→ L1→ … → Ln-1→ Ln
12+
请将其重新排列后变为:
13+
L0→Ln→L1→Ln-1→L2→Ln-2→ …
14+
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
15+
示例 1:
16+
输入: head = [1,2,3,4]
17+
输出: [1,4,2,3]
18+
示例 2:
19+
输入: head = [1,2,3,4,5]
20+
输出: [1,5,2,4,3]
21+
提示:
22+
链表的长度范围为 [1, 5 * 10^4]
23+
1 <= node.val <= 1000
24+
*/
25+
public class Question_143 {
26+
27+
// 时间复杂度是O(N),空间复杂度是O(1)
28+
public void solution1(ListNode head) {
29+
if(head == null){
30+
return;
31+
}
32+
// 获得中间节点
33+
ListNode mid = findMid(head);
34+
35+
// 中间节点之后的部分进行反转
36+
ListNode head2 = mid.next;
37+
// 切割链表,分成前后两部分
38+
mid.next = null;
39+
head2 = reverseList(head2);
40+
41+
// 合并
42+
mergeList(head,head2);
43+
}
44+
45+
private ListNode findMid(ListNode head) {
46+
ListNode slow = head;
47+
ListNode fast = head;
48+
while(fast.next != null && fast.next.next != null) {
49+
slow = slow.next;
50+
fast = fast.next.next;
51+
}
52+
return slow;
53+
}
54+
55+
private ListNode reverseList(ListNode head) {
56+
ListNode pre = null;
57+
ListNode cur = head;
58+
while(cur != null){
59+
ListNode tmp = cur.next;
60+
cur.next = pre;
61+
pre = cur;
62+
cur = tmp;
63+
}
64+
return pre;
65+
}
66+
67+
private void mergeList(ListNode head1, ListNode head2) {
68+
ListNode next1 = null;
69+
ListNode next2 = null;
70+
while(head1 != null && head2 != null) {
71+
next1 = head1.next;
72+
next2 = head2.next;
73+
74+
head1.next = head2;
75+
head1 = next1;
76+
77+
head2.next = head1;
78+
head2 = next2;
79+
}
80+
}
81+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.cjl.leetcode;
2+
3+
/*
4+
440. 字典序的第K小数字
5+
问题描述:
6+
给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字。
7+
注意:
8+
1 ≤ k ≤ n ≤ 10^9。
9+
示例:
10+
输入:n: 13 k: 2
11+
输出:10
12+
解释:字典序的排列是 [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9],所以第二小的数字是 10。
13+
*/
14+
public class Question_440 {
15+
16+
// 时间复杂度是O(k),空间复杂度是O(1)
17+
public int solution1(int n, int k) {
18+
int cur = 1;
19+
k = k - 1;
20+
while(k > 0) {
21+
int num = getCount(n, cur, cur + 1);
22+
if(num <= k) {
23+
// 若第k个数不在以cur为根节点的树上,则往右移动到兄弟节点
24+
cur += 1;
25+
k -= num;
26+
}else{
27+
// 第k个数在以cur为根节点的树上,往子节点移动
28+
cur *= 10;
29+
k -= 1;
30+
}
31+
}
32+
return cur;
33+
}
34+
35+
private int getCount(int n, int first, int last){
36+
int num = 0;
37+
while(first <= n) {
38+
// 比如n是195的情况195到100有96个数
39+
num += Math.min(n+1, last) - first;
40+
// 防止溢出
41+
if(first <= n / 10){
42+
first *= 10;
43+
last *= 10;
44+
} else {
45+
break;
46+
}
47+
}
48+
return num;
49+
}
50+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.cjl.leetcode;
2+
3+
import java.util.*;
4+
5+
/*
6+
56. 合并区间
7+
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。
8+
请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
9+
示例 1:
10+
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
11+
输出:[[1,6],[8,10],[15,18]]
12+
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
13+
示例2:
14+
输入:intervals = [[1,4],[4,5]]
15+
输出:[[1,5]]
16+
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
17+
提示:
18+
1 <= intervals.length <= 10^4
19+
intervals[i].length == 2
20+
0 <= starti <= endi <= 10^4
21+
*/
22+
public class Question_56 {
23+
24+
public int[][] solution1(int[][] intervals) {
25+
if(intervals == null || intervals.length == 1){
26+
return intervals;
27+
}
28+
List<Integer> arr = new ArrayList<>();
29+
// 按最小界排序
30+
Arrays.sort(intervals, Comparator.comparingInt(a -> a[0]));
31+
// 记录前面的最大界
32+
int preEnd = -1;
33+
for (int[] interval : intervals) {
34+
if (interval[0] > preEnd) {
35+
// 当前最小界大于前面的最大界,不能合并
36+
arr.add(interval[0]);
37+
arr.add(interval[1]);
38+
}else if (interval[1] > preEnd){
39+
// 当前最小界小于或等于前面的最大界,并且当前最大界大于前面的最大界,可合并
40+
arr.remove(arr.size() - 1);
41+
arr.add(interval[1]);
42+
}
43+
preEnd = Math.max(preEnd,interval[1]);
44+
}
45+
int[][] res = new int[arr.size()/2][2];
46+
for (int i = 0; i < arr.size(); i++) {
47+
res[i/2][i%2] = arr.get(i);
48+
}
49+
return res;
50+
}
51+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.cjl.leetcode;
2+
3+
/*
4+
7. 整数反转
5+
问题描述:
6+
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
7+
如果反转后整数超过 32 位的有符号整数的范围[−2^31, 2^31− 1] ,就返回 0。
8+
假设环境不允许存储 64 位整数(有符号或无符号)。
9+
示例 1:
10+
输入:x = 123
11+
输出:321
12+
示例 2:
13+
输入:x = -123
14+
输出:-321
15+
示例 3:
16+
输入:x = 120
17+
输出:21
18+
示例 4:
19+
输入:x = 0
20+
输出:0
21+
提示:
22+
-2^31 <= x <= 2^31 - 1
23+
*/
24+
public class Question_7 {
25+
26+
// 时间复杂度是O(1),空间复杂度是O(1)
27+
public static int solution1(int x){
28+
boolean flag = x > 0;
29+
if(!flag && Math.abs(x) >= Integer.MAX_VALUE) {
30+
return 0;
31+
}
32+
int res = 0;
33+
int temp = Math.abs(x);
34+
while(temp != 0) {
35+
if(res > (Integer.MAX_VALUE - temp % 10)/10){
36+
return 0;
37+
}else{
38+
res = res * 10 + temp % 10;
39+
temp /= 10;
40+
}
41+
}
42+
return flag ? res: -res;
43+
}
44+
}

0 commit comments

Comments
 (0)