Skip to content

Commit

Permalink
'1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Ainevsia committed Jul 17, 2023
1 parent c0faee9 commit 912416d
Show file tree
Hide file tree
Showing 6 changed files with 311 additions and 2 deletions.
3 changes: 3 additions & 0 deletions notes/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@
- [206. 反转链表](./day3/lc206.md)
- [Day 4](./day4.md)
- [24. 两两交换链表中的节点](./day4/lc24.md)
- [19. 删除链表的倒数第N个节点](./day4/lc19.md)
- [面试题 02.07. 链表相交](./day4/lc02.07.md)
- [142. 环形链表II](./day4/lc142.md)
- [Day 5](./day5.md)
42 changes: 42 additions & 0 deletions notes/src/day4.md
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

58 changes: 58 additions & 0 deletions notes/src/day4/lc02.07.md
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

```
## 学习感想

看解析之前没有想到这个做法

重点是尾部对其,
38 changes: 38 additions & 0 deletions notes/src/day4/lc142.md
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
```

## 学习感想

一刷 数学题 不会,快慢指针会的,但是数学推导没有想到
114 changes: 114 additions & 0 deletions notes/src/day4/lc19.md
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.
58 changes: 56 additions & 2 deletions notes/src/day4/lc24.md
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头节点,然后按照操作来把节点从原来的链表里取出来插入新的链表中,根本不用想怎么修改指针

0 comments on commit 912416d

Please sign in to comment.