Skip to content

Commit 2664a61

Browse files
authored
Merge pull request #1 from algorithm001/master
Pull the latest code.
2 parents 73e0891 + cd4a798 commit 2664a61

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2446
-3
lines changed

Week_01/.DS_Store

6 KB
Binary file not shown.

Week_01/id_118/NOTE.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,58 @@
1-
# 学习笔记
1+
# 本周学习重点
2+
3+
由于时间有限,本周学习重点放在 链表和数组 这两类题型上。
4+
5+
一些比较有收获的点是:
6+
1. 同一类型的题目,可以从 easy 开始做,然后到 middle 最后再到 hard,层层递进,因为难题都是由简单题目演进而来的,由浅入深会比较容易接受,
7+
2. 做题前,先对“已知信息”做收集,然后再看利用已有知识,如何达到题目要求。
8+
3. 解题思路可以靠画图辅助梳理,解法也可以在纸上走一遍进行推导,不要上来就写代码。
9+
4. 最后,同一题可以尝试用不同的方法去解决。
10+
11+
12+
# 链表题型总结
13+
本周截止写这篇总结时,做完的链表题目有:
14+
- [leetcode.83.删除排序链表中的重复元素](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/)
15+
- [leetcode.21.合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/)
16+
- [leetcode.24.两两交换链表中的节点](https://leetcode-cn.com/problems/swap-nodes-in-pairs/)
17+
- [leetcode.142.环形链表2](https://leetcode-cn.com/problems/linked-list-cycle-ii/)
18+
- [leetcode.25.k个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/)
19+
20+
一些小总结:
21+
- 链表题型,怎么都跑不了一些基本操作:插入节点(头、尾、中间),删除节点(头、尾、中间),相邻节点交换。所以,必须对这些操作熟悉的不能再熟悉。
22+
- 链表题型,比较常见的是:
23+
- 删除指定条件的元素(eg:删除重复元素、删除倒数第k个节点、删除中间节点或a/b处的节点)
24+
- 链表反转(eg:整体反转、两两反转、k个一组反转)
25+
- 环的问题(eg:判断链表中是否有环、找到链表环的第一个节点)
26+
- 两个链表的问题(eg:两个有序链表合并、求两个有序链表的公共部分)
27+
- 。。。。。。
28+
- 链表问题的解法:
29+
- 常规题,一般是辅助指针,加上常规的插入删除交换操作就可以搞定。
30+
- 部分题型需要结合哈希表。
31+
- 有一些题目需要用些小技巧,比如多次迭代、快慢指针等。
32+
- 写代码时需要注意的点:
33+
- 注意不要丢节点,有一些操作的前后顺序很重要,一不小心就把后面的整条链给丢掉了。
34+
- 也不要造成环,链表拆解或合并,最容易出现这种情况,一定要在纸上把流程捋清晰了再写代码。
35+
- 有时候,加一个哨兵节点能够简化操作。
36+
37+
38+
# 数组题型总结
39+
本周截止到写这篇总结时,做完的链表题目有:
40+
- [leetcode.905.按奇偶排序数组](https://leetcode-cn.com/problems/sort-array-by-parity/)
41+
- [leetcpde.922.按奇偶排序数组2](https://leetcode-cn.com/problems/sort-array-by-parity-ii/)
42+
- [leetcode.153.寻找旋转排序数组中的最小值](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/submissions/)
43+
- [leetcode.33.搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/description/)
44+
- [leetcode.704.二分查找](https://leetcode-cn.com/problems/binary-search/)
45+
46+
一些小总结:
47+
- 数组题型相比链表就比较杂了,我做过的题目也不是太多,以我浅薄的经验稍稍总结一下。
48+
- 数组的特点基本操作,一般是:数据移动交换或删除。不一般是:排序、二分、以及其他图算法等等。
49+
- 我目前做的这几道题,基本上都是排序和二分查找。几个关键点吧:
50+
- 排序题目要么是冒泡、插入、归并等这些经典的算法题,要么是这些算法题的变种。其中以归并、快排的思路居多,也偶尔有一些插入排序的变形题。
51+
- 查找类题目,只要要求了 O(logn),基本上就二分没跑了,实现上可能能用递归解决。
52+
- 写代码时:
53+
- 首先要注意数组越界问题。
54+
- 接下来是需要用到的索引指针的初始化的问题。
55+
- 以及,非常琐碎的边界点的问题,比如 是 > 还是 >=,是 left=middle 还是 left = middle+1。
56+
57+
58+

Week_01/id_118/leetcode_142_118.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* https://leetcode-cn.com/problems/linked-list-cycle-ii/
3+
*
4+
* Definition for singly-linked list.
5+
* class ListNode {
6+
* int val;
7+
* ListNode next;
8+
* ListNode(int x) {
9+
* val = x;
10+
* next = null;
11+
* }
12+
* }
13+
*/
14+
public class Solution {
15+
public ListNode detectCycle(ListNode head) {
16+
// 不允许修改给定的链表。也就是不能在数据节点做标记,也不能修改链表节点指向。
17+
// 第一种解法哈希表,第二种解法快慢指针。
18+
19+
// 1. 边界处理
20+
if(head == null || head.next == null){
21+
return null;
22+
}
23+
24+
// 2. 加哨兵节点
25+
ListNode guard = new ListNode(-1);
26+
guard.next = head;
27+
28+
// 3. 定义快慢指针
29+
ListNode fast = guard;
30+
ListNode slow = guard;
31+
32+
// 4. 遍历,检查是否有环。
33+
// - 要是没环的话,会直接抛出去
34+
// - 要是有环的话,则快慢指针一定会相遇,退出循环
35+
while(true){
36+
if(fast.next == null || fast.next.next==null){
37+
return null;
38+
}
39+
slow = slow.next;
40+
fast = fast.next.next;
41+
if(slow == fast){
42+
break;
43+
}
44+
}
45+
46+
// 5. 查找环的位置
47+
slow = guard;
48+
while(slow != fast){
49+
slow = slow.next;
50+
fast= fast.next;
51+
}
52+
return slow;
53+
}
54+
}

Week_01/id_118/leetcode_153_118.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/submissions/
3+
*/
4+
class Solution {
5+
public int findMin(int[] nums) {
6+
// 从旋转节点分隔,左侧数据 > 右侧数据,所以找到这个旋转点就能找到最小值。
7+
8+
// 用二分的方式,进行递归
9+
// - nums[left] > nums[right] 则最小值一定在左边
10+
// - nums[left] < nums[right] 则最小值一定在右边
11+
// 递归终止条件为:left==right 或 left+1==right,最小值为 nums[right]。
12+
13+
// PS:有一个点要特别需要注意的是,如果本身已经有序了(第一个点<最后一个点),就不需要这么找了,第一个就是最小值。
14+
15+
if(nums[0] < nums[nums.length-1]){
16+
return nums[0];
17+
}
18+
return findMin(nums,0,nums.length-1);
19+
}
20+
21+
int findMin(int[] nums,int left,int right){
22+
// 找到反转位置
23+
if(left == right || left+1==right){
24+
return nums[right];
25+
}
26+
int middle = left+(right-left)/2;
27+
if(nums[left] > nums[middle]){
28+
return findMin(nums,left,middle);
29+
}else{
30+
return findMin(nums,middle,right);
31+
}
32+
}
33+
}

Week_01/id_118/leetcode_21_118.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
/**
3+
*
4+
* https://leetcode-cn.com/problems/merge-two-sorted-lists/submissions/
5+
*
6+
* Definition for singly-linked list.
7+
* public class ListNode {
8+
* int val;
9+
* ListNode next;
10+
* ListNode(int x) { val = x; }
11+
* }
12+
*/
13+
class Solution {
14+
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
15+
16+
// 1. 边界处理:两个都为null或任意一个为null
17+
if(l1==null || l2==null ){
18+
return l1 == null ? l2 : l1;
19+
}
20+
21+
// 2. 初始化新链表中的节点。
22+
// - 为了简化处理,初始化一个头结点作为哨兵节点,值为0。
23+
// - 再初始化一个临时指针,指向头结点,从头开始往链表上挂节点。
24+
ListNode head = new ListNode(0);
25+
ListNode current = head;
26+
27+
// 3. 同时遍历两个链表,哪个头结点值最小,则把哪个节点的头拆下来
28+
// - 注意,拆头结点的时候,千万别把指针拆丢了
29+
while(l1!=null && l2!=null){
30+
if(l1.val<=l2.val){
31+
current.next = l1;
32+
l1=l1.next;
33+
}else{
34+
current.next = l2;
35+
l2=l2.next;
36+
}
37+
current=current.next;
38+
current.next = null;
39+
}
40+
41+
// 4. 边界处理:可能某一个指针还没走完,直接无脑追加上就好了
42+
if(l1!=null){
43+
current.next = l1;
44+
}
45+
if(l2!=null){
46+
current.next = l2;
47+
}
48+
49+
// 5. 最后,返回 head.next,因为head节点数据无意义
50+
return head.next;
51+
52+
}
53+
}

Week_01/id_118/leetcode_24_118.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* https://leetcode-cn.com/problems/swap-nodes-in-pairs/
3+
*
4+
* Definition for singly-linked list.
5+
* public class ListNode {
6+
* int val;
7+
* ListNode next;
8+
* ListNode(int x) { val = x; }
9+
* }
10+
*/
11+
class Solution {
12+
public ListNode swapPairs(ListNode head) {
13+
14+
// 1. 边界:空链表或只有一个节点
15+
if(head==null || head.next == null){
16+
return head;
17+
}
18+
19+
// 2. 为了方便处理,需要加一个哨兵节点,指向 head
20+
ListNode guard = new ListNode(0);
21+
guard.next = head;
22+
23+
// 3. 然后,两个节点的交换需要涉及到其前后节点,加起来共四个节点,按顺序分别将他们定义为:
24+
// start_left,要交换两个节点中起点的前一个节点。初始为 guard
25+
// start,要交换的起点。初始为 head
26+
// end,要交换的终点。初始为 head.next
27+
// end_right,要交换的两个节点中终点的后一个节点。初始为 head.next.next。这个节点有可能为空
28+
ListNode start_left = guard;
29+
ListNode start = head;
30+
ListNode end = head.next;
31+
ListNode end_right = head.next.next;
32+
33+
// 4. 开始做节点交换和指针移动,end==null时停止
34+
while(end!=null){
35+
// 先交换
36+
start_left.next = end;
37+
start.next = end_right;
38+
end.next = start;
39+
// 后移动。注意判断接下来是否还有两个非空节点
40+
if(end_right == null || end_right.next == null){
41+
break;
42+
}
43+
start_left = start;
44+
start = start_left.next;
45+
end = start.next;
46+
end_right = end.next;
47+
}
48+
49+
// 5. 最后返回 guard.next。注意,这里不要返回 head,因为head 已经被交换到第二个节点了。
50+
return guard.next;
51+
}
52+
}

Week_01/id_118/leetcode_25_118.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* https://leetcode-cn.com/problems/reverse-nodes-in-k-group/
3+
*
4+
* Definition for singly-linked list.
5+
* public class ListNode {
6+
* int val;
7+
* ListNode next;
8+
* ListNode(int x) { val = x; }
9+
* }
10+
*/
11+
class Solution {
12+
public ListNode reverseKGroup(ListNode head, int k) {
13+
14+
// 1. 边界值处理:空指针、一个节点、k小于等于1
15+
if(head==null || head.next==null || k<=1){
16+
return head;
17+
}
18+
19+
// 2. 加哨兵节点
20+
ListNode guard = new ListNode(0);
21+
guard.next = head;
22+
23+
// 3. 左侧已翻转完链表的尾节点,并将其指向 null,避免产生环
24+
ListNode left = guard;
25+
left.next = null;
26+
27+
// 4. head 不为 null,则持续翻转
28+
while(head!=null){
29+
30+
// 判断剩下的部分是否还有 k 个节点能翻转
31+
if(!hasEnoughNode(head,k)){
32+
break;
33+
}
34+
35+
// 把头结点提拉出来,作为翻转部分的第一个节点
36+
ListNode new_tail = head;// 新翻转链表的尾节点
37+
ListNode new_head = head;// 新翻转链表的头结点
38+
head = head.next;
39+
new_tail.next = null;// 这是为了避免误操作搞出环来
40+
41+
// 然后再找k-1个节点出来,插到链表头
42+
int count = k-1;
43+
while(count!=0){
44+
ListNode tmp = head;
45+
head = head.next;
46+
tmp.next = new_head;
47+
new_head = tmp;
48+
count--;
49+
}
50+
51+
// 左边的链表,和新翻转的链表串起来
52+
left.next = new_head;
53+
54+
// 移动尾巴
55+
left = new_tail;
56+
}
57+
58+
// 5.最后再把没反转的部分给链上
59+
left.next = head;
60+
61+
// 6. 返回
62+
return guard.next;
63+
}
64+
65+
66+
// 判断后面是否还有足够的节点可以反转。
67+
boolean hasEnoughNode(ListNode head,int k){
68+
ListNode tmp = head;
69+
while(k!=0){
70+
if(tmp == null){
71+
return false;
72+
}
73+
tmp=tmp.next;
74+
k--;
75+
}
76+
return true;
77+
}
78+
79+
}

Week_01/id_118/leetcode_33_118.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* https://leetcode-cn.com/problems/search-in-rotated-sorted-array/
3+
*/
4+
class Solution {
5+
public int search(int[] A, int target) {
6+
// 非递归
7+
8+
// 边界处理
9+
if(A.length<1){
10+
return -1;
11+
}
12+
13+
// 定义左右索引
14+
int left =0;
15+
int right = A.length-1;
16+
17+
// 折半搜索。需要特别注意,用 >= 还是 >,用 left=mid 还是 left=mid+1。十分重要!!!
18+
while(left <= right){
19+
int mid = (left+right)/2;
20+
21+
if(A[mid] == target){
22+
return mid;
23+
}
24+
25+
if(A[mid] < A[right]){
26+
if(target>A[mid] && target<=A[right]){
27+
left=mid+1;
28+
}
29+
else{
30+
right = mid-1;
31+
}
32+
}else{
33+
if(target>=A[left] && target<A[mid]){
34+
right=mid-1;
35+
}else{
36+
left=mid+1;
37+
}
38+
}
39+
}
40+
// 没找到
41+
return -1;
42+
}
43+
44+
}

0 commit comments

Comments
 (0)