-
Notifications
You must be signed in to change notification settings - Fork 1
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
145 additions
and
82 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
81 changes: 0 additions & 81 deletions
81
src/leetcode/0082-remove-duplicates-from-sorted-list-ii/src/main.rs
This file was deleted.
Oops, something went wrong.
File renamed without changes.
3 changes: 3 additions & 0 deletions
3
src/leetcode/0082.remove-duplicates-from-sorted-list-ii/index.md
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,3 @@ | ||
# 0082. 删除排序链表中的重复元素 II Remove Duplicates from Sorted List II | ||
|
||
[问题描述](../problems/0082.remove-duplicates-from-sorted-list-ii/content.html) |
139 changes: 139 additions & 0 deletions
139
src/leetcode/0082.remove-duplicates-from-sorted-list-ii/src/main.rs
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,139 @@ | ||
// Copyright (c) 2023 Xu Shaohua <[email protected]>. All rights reserved. | ||
// Use of this source is governed by General Public License that can be | ||
// found in the LICENSE file. | ||
|
||
#![allow(dead_code)] | ||
|
||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct ListNode { | ||
pub val: i32, | ||
pub next: Option<Box<ListNode>>, | ||
} | ||
|
||
impl ListNode { | ||
#[inline] | ||
#[must_use] | ||
pub const fn new(val: i32) -> Self { | ||
Self { val, next: None } | ||
} | ||
|
||
pub fn from_slice(slice: &[i32]) -> Option<Box<Self>> { | ||
let mut list = None; | ||
for &val in slice.iter().rev() { | ||
list = Some(Box::new(Self { val, next: list })); | ||
} | ||
list | ||
} | ||
|
||
pub fn debug_print(head: &Option<Box<Self>>) { | ||
print!("head: ["); | ||
let mut node_ref = head; | ||
while node_ref.is_some() { | ||
print!("{}, ", node_ref.as_ref().unwrap().val); | ||
node_ref = &node_ref.as_ref().unwrap().next; | ||
} | ||
println!("]"); | ||
} | ||
|
||
pub fn debug_print2(head: &Option<Box<Self>>) -> Option<Box<Self>> { | ||
print!("head: ["); | ||
if head.is_some() { | ||
let mut node_ref: &ListNode = head.as_ref()?; | ||
print!("{}, ", node_ref.val); | ||
while let Some(next_ref) = node_ref.next.as_ref() { | ||
print!("{}, ", next_ref.val); | ||
node_ref = node_ref.next.as_ref()?; | ||
} | ||
} | ||
println!("]"); | ||
None | ||
} | ||
} | ||
|
||
pub fn delete_duplicates1(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> { | ||
if head.is_none() { | ||
return head; | ||
} | ||
|
||
// dummy_head 的下一个节点是 head. | ||
// 当 head 及其后面的节点是重复数值时, 这样设计就可以简化处理. | ||
// 因为最终返回的, 是 dummy_head->next | ||
let mut dummy_head = Some(Box::new(ListNode { | ||
val: i32::MIN, | ||
next: head, | ||
})); | ||
|
||
// 这里, 不再创建 prev 节点, current 节点就当作 prev 节点使用. | ||
// 这样为了方便移除后面的节点. | ||
let mut current: &mut ListNode = dummy_head.as_mut()?; | ||
|
||
loop { | ||
if let Some(next_ref) = current.next.as_mut() { | ||
// current->next.val == current->next->next.val | ||
if let Some(next_next_ref) = next_ref.next.as_mut() { | ||
if next_ref.val == next_next_ref.val { | ||
// 移除所有重复节点 | ||
let mut temp: Option<Box<ListNode>> = current.next.take(); | ||
// temp.val == temp->next.val | ||
while temp.is_some() | ||
&& temp.as_ref()?.next.is_some() | ||
&& temp.as_ref()?.val == temp.as_ref()?.next.as_ref()?.val | ||
{ | ||
// 这里 temp 指向的当前节点就被 drop 了. | ||
// temp = temp->next; | ||
temp = temp.as_mut()?.next.take(); | ||
} | ||
// 将 current 的下一个节点指向 temp 的下一个节点, | ||
// 在下个循环时, 将开始检查它的值. | ||
// current->next = temp->next; | ||
current.next = temp.as_mut()?.next.take(); | ||
} else { | ||
// 跳到下一个节点 | ||
// current = current->next; | ||
current = current.next.as_mut()?; | ||
} | ||
} else { | ||
// 当 current->next->next 为 None 是, 说明 current->next.val 不重复, | ||
// 遍历也完成了. | ||
break; | ||
} | ||
} else { | ||
// 当 current->next 为 None 是, 说明遍历完成. | ||
break; | ||
} | ||
} | ||
|
||
dummy_head.as_mut()?.next.take() | ||
} | ||
|
||
pub type SolutionFn = fn(Option<Box<ListNode>>) -> Option<Box<ListNode>>; | ||
|
||
fn check_solution(func: SolutionFn) { | ||
let list = ListNode::from_slice(&[1, 2, 3, 3, 4, 4, 5]); | ||
let result = func(list); | ||
ListNode::debug_print(&result); | ||
//println!("result: {result:?}"); | ||
let expected_result = ListNode::from_slice(&[1, 2, 5]); | ||
assert_eq!(result, expected_result); | ||
|
||
let list = ListNode::from_slice(&[1, 1, 1, 2, 3]); | ||
let result = func(list); | ||
ListNode::debug_print(&result); | ||
//println!("result: {result:?}"); | ||
let expected_result = ListNode::from_slice(&[2, 3]); | ||
assert_eq!(result, expected_result); | ||
} | ||
|
||
fn main() { | ||
check_solution(delete_duplicates1); | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::{check_solution, delete_duplicates1}; | ||
|
||
#[test] | ||
fn test_solution1() { | ||
check_solution(delete_duplicates1); | ||
} | ||
} |
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