-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
311 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# 第二章 链表part02 | ||
|
||
● day 1 任务以及具体安排:https://docs.qq.com/doc/DUG9UR2ZUc3BjRUdY | ||
● day 2 任务以及具体安排:https://docs.qq.com/doc/DUGRwWXNOVEpyaVpG | ||
● day 3 任务以及具体安排:https://docs.qq.com/doc/DUGdqYWNYeGhlaVR6 | ||
|
||
今日任务 | ||
|
||
● 24. 两两交换链表中的节点 | ||
● 19.删除链表的倒数第N个节点 | ||
● 面试题 02.07. 链表相交 | ||
● 142.环形链表II | ||
● 总结 | ||
|
||
详细布置 | ||
|
||
## 24. 两两交换链表中的节点 | ||
|
||
用虚拟头结点,这样会方便很多。 | ||
|
||
本题链表操作就比较复杂了,建议大家先看视频,视频里我讲解了注意事项,为什么需要temp保存临时节点。 | ||
|
||
题目链接/文章讲解/视频讲解: https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html | ||
|
||
## 19.删除链表的倒数第N个节点 | ||
|
||
双指针的操作,要注意,删除第N个节点,那么我们当前遍历的指针一定要指向 第N个节点的前一个节点,建议先看视频。 | ||
|
||
题目链接/文章讲解/视频讲解:https://programmercarl.com/0019.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B9.html | ||
|
||
## 面试题 02.07. 链表相交 | ||
|
||
本题没有视频讲解,大家注意 数值相同,不代表指针相同。 | ||
|
||
题目链接/文章讲解:https://programmercarl.com/%E9%9D%A2%E8%AF%95%E9%A2%9802.07.%E9%93%BE%E8%A1%A8%E7%9B%B8%E4%BA%A4.html | ||
|
||
## 142.环形链表II | ||
|
||
算是链表比较有难度的题目,需要多花点时间理解 确定环和找环入口,建议先看视频。 | ||
|
||
题目链接/文章讲解/视频讲解:https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# 面试题 02.07. 链表相交 | ||
|
||
|
||
## 题目描述 | ||
|
||
|
||
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 | ||
|
||
你能否设计一个时间复杂度 O(n) 、仅用 O(1) 内存的解决方案? | ||
|
||
## 解题思路 | ||
|
||
这题没有rust选 | ||
|
||
```python | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: | ||
la = 1 | ||
lb = 1 | ||
ptra = headA | ||
ptrb = headB | ||
if ptra is None or ptrb is None: | ||
return None | ||
while ptra.next != None: | ||
la += 1 | ||
ptra = ptra.next | ||
while ptrb.next != None: | ||
lb += 1 | ||
ptrb = ptrb.next | ||
if la < lb: | ||
ptra, ptrb = headB, headA | ||
else: | ||
ptra, ptrb = headA, headB | ||
|
||
d = abs(la - lb) | ||
print(d, la, lb) | ||
for i in range(d): | ||
ptra = ptra.next | ||
for i in range(min(la,lb)): | ||
if ptra is ptrb: | ||
return ptra | ||
else: | ||
ptra = ptra.next | ||
ptrb = ptrb.next | ||
return None | ||
|
||
``` | ||
## 学习感想 | ||
|
||
看解析之前没有想到这个做法 | ||
|
||
重点是尾部对其, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# 142.环形链表II | ||
## 题目描述 | ||
|
||
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 | ||
|
||
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。 | ||
|
||
不允许修改 链表。 | ||
|
||
## 解题思路 | ||
|
||
```python | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
fast = head | ||
slow = head | ||
while fast != None and fast.next != None and fast.next.next != None: | ||
fast = fast.next.next | ||
slow = slow.next | ||
if fast is slow: | ||
# found in loop | ||
newindex = head | ||
while not newindex is fast: | ||
fast = fast.next | ||
newindex = newindex.next | ||
return fast | ||
return None | ||
``` | ||
|
||
## 学习感想 | ||
|
||
一刷 数学题 不会,快慢指针会的,但是数学推导没有想到 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# 19. 删除链表的倒数第 N 个结点 | ||
|
||
## 题目描述 | ||
|
||
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 | ||
|
||
|
||
## 解题思路 | ||
|
||
之前用dummy 重新构造新的链表来做的 | ||
|
||
```rust | ||
|
||
struct Solution {} | ||
|
||
// Definition for singly-linked list. | ||
#[derive(PartialEq, Eq, Clone, Debug)] | ||
pub struct ListNode { | ||
pub val: i32, | ||
pub next: Option<Box<ListNode>> | ||
} | ||
|
||
impl ListNode { | ||
#[inline] | ||
fn new(val: i32) -> Self { | ||
ListNode { | ||
next: None, | ||
val | ||
} | ||
} | ||
} | ||
|
||
impl Solution { | ||
pub fn remove_nth_from_end(mut head: Option<Box<ListNode>>, n: i32) -> Option<Box<ListNode>> { | ||
let mut dummy = ListNode::new(-1); | ||
while let Some(mut x) = head { | ||
head = x.next; | ||
x.next = dummy.next; | ||
dummy.next = Some(x); | ||
} | ||
let mut ptr = &mut dummy; | ||
for _ in 1..n { ptr = ptr.next.as_deref_mut().unwrap() } | ||
let drop = ptr.next.take(); | ||
ptr.next = drop?.next.take(); | ||
head = dummy.next.take(); | ||
while let Some(mut x) = head { | ||
head = x.next; | ||
x.next = dummy.next; | ||
dummy.next = Some(x); | ||
} | ||
dummy.next | ||
} | ||
} | ||
``` | ||
|
||
|
||
|
||
## 学习感想 | ||
|
||
双指针法这道题用safe rust没法写,因为需要同时持有链表的两个引用,并且头部的引用还必须是可变引用,这是没法做到的 | ||
|
||
```rust | ||
|
||
struct Solution {} | ||
|
||
// Definition for singly-linked list. | ||
#[derive(PartialEq, Eq, Clone, Debug)] | ||
pub struct ListNode { | ||
pub val: i32, | ||
pub next: Option<Box<ListNode>> | ||
} | ||
|
||
impl ListNode { | ||
#[inline] | ||
fn new(val: i32) -> Self { | ||
ListNode { | ||
next: None, | ||
val | ||
} | ||
} | ||
} | ||
impl Solution { | ||
pub fn remove_nth_from_end(head: Option<Box<ListNode>>, n: i32) -> Option<Box<ListNode>> { | ||
unsafe { | ||
let dummy = ListNode { val: -1, next: head }; | ||
let mut ptr = &dummy; | ||
for _ in 0..n { ptr = ptr.next.as_deref()? } | ||
let mut ptr2 = &dummy as *const ListNode as *mut ListNode; | ||
while ptr.next.is_some() { | ||
ptr = ptr.next.as_deref()?; | ||
ptr2 = (*ptr2).next.as_deref()? as *const ListNode as *mut ListNode; | ||
} | ||
let mut rigoff = (*ptr2).next.take()?; | ||
let nxt = rigoff.next.take(); | ||
(*ptr2).next = nxt; | ||
dummy.next | ||
} | ||
} | ||
} | ||
``` | ||
|
||
所以这就是我用unsafe的原因 | ||
|
||
# Unsafe Superpowers | ||
|
||
To switch to unsafe Rust, use the unsafe keyword and then start a new block that holds the unsafe code. You can take five actions in unsafe Rust that you can’t in safe Rust, which we call unsafe superpowers. Those superpowers include the ability to: | ||
|
||
- Dereference a raw pointer | ||
- Call an unsafe function or method | ||
- Access or modify a mutable static variable | ||
- Implement an unsafe trait | ||
- Access fields of unions | ||
|
||
**It’s important to understand that unsafe doesn’t turn off the borrow checker or disable any other of Rust’s safety checks: if you use a reference in unsafe code, it will still be checked.** The unsafe keyword only gives you access to these five features that are then not checked by the compiler for memory safety. You’ll still get some degree of safety inside of an unsafe block. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,58 @@ | ||
# | ||
# 24. 两两交换链表中的节点 | ||
|
||
## 题目描述 | ||
|
||
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 | ||
|
||
|
||
## 解题思路 | ||
## 学习感想 | ||
|
||
? 还是一边出 一边入 | ||
|
||
```rust | ||
|
||
struct Solution {} | ||
|
||
// Definition for singly-linked list. | ||
#[derive(PartialEq, Eq, Clone, Debug)] | ||
pub struct ListNode { | ||
pub val: i32, | ||
pub next: Option<Box<ListNode>> | ||
} | ||
|
||
impl ListNode { | ||
#[inline] | ||
fn new(val: i32) -> Self { | ||
ListNode { | ||
next: None, | ||
val | ||
} | ||
} | ||
} | ||
|
||
impl Solution { | ||
pub fn swap_pairs(mut head: Option<Box<ListNode>>) -> Option<Box<ListNode>> { | ||
let mut dummy = Box::new(ListNode { val: 0, next: None }); | ||
let mut cdummy = &mut dummy; | ||
while let Some(mut x) = head.take() { | ||
if x.next.is_none() { | ||
cdummy.next = Some(x); | ||
return dummy.next; | ||
} | ||
if let Some(mut y) = x.next.take() { | ||
head = y.next.take(); | ||
y.next = Some(x); | ||
cdummy.next = Some(y); | ||
cdummy = cdummy.next.as_mut().unwrap(); | ||
cdummy = cdummy.next.as_mut().unwrap(); | ||
} | ||
} | ||
dummy.next | ||
} | ||
} | ||
|
||
``` | ||
|
||
## 学习感想 | ||
|
||
我发现我做链表逆序 两两交换的时候都是直接新建一个存返回链表的dummy头节点,然后按照操作来把节点从原来的链表里取出来插入新的链表中,根本不用想怎么修改指针 |