list

lc430

DFS遍历链表

把每个节点的++子链表"拉直"插入到当前节点和下一个节点之间++

最终返回扁平化后的头节点

class Solution {

public:

Node* dfs(Node *now){

if(now == NULL) return NULL;

Node* ans = NULL;

if(now->child){

Node *t1 = now->child;

Node *t2 = dfs(now->child);

++Node *t3 = now->next;++

now->child = NULL;

now->next = t1;

t1->prev = now;

++t2->next = t3;++

if(t3 == NULL) return t2;

t3->prev = t2;

++ans = dfs(t3);++

}

else

{

if(now->next == NULL) return now;

ans = dfs(now->next);

}

return ans;

}

Node* flatten(Node* head) {

dfs(head);

return head;

}

};

rust

#derive(Debug, Clone, PartialEq, Eq)

pub struct Node {

pub val: i32,

pub prev: Option<Rc<RefCell<Node>>>,

pub next: Option<Rc<RefCell<Node>>>,

pub child: Option<Rc<RefCell<Node>>>,

}

impl Node {

#inline

pub fn new(val: i32) -> Self {

Node {

val,

prev: None,

next: None,

child: None,

}

}

}

use std::rc::Rc;

use std::cell::RefCell;

struct Solution;

impl Solution {

pub fn flatten(head: Option<Rc<RefCell<Node>>>) -> Option<Rc<RefCell<Node>>> {

if let Some(head) = head.clone() {

Self::dfs(head);

}

head

}

fn dfs(node: Rc<RefCell<Node>>) -> Rc<RefCell<Node>> {

let mut node_mut = node.borrow_mut();

if let Some(child) = node_mut.child.take() {

let next = node_mut.next.clone();

let child_tail = Self::dfs(child.clone());

node_mut.next = Some(child.clone());

child.borrow_mut().prev = Some(node.clone());

child_tail.borrow_mut().next = next.clone();

if let Some(next) = next {

next.borrow_mut().prev = Some(child_tail.clone());

}

if let Some(next) = next {

drop(node_mut);

return Self::dfs(next);

} else {

return child_tail;

}

}

if let Some(next) = node_mut.next.clone() {

drop(node_mut);

Self::dfs(next)

} else {

drop(node_mut);

node

}

}

}

  1. Rc<RefCell>:共享所有权+内部可变性,安全管理链表节点的引用与修改;

  2. Option枚举:优雅处理空指针场景,避免野指针;

  3. take()方法:转移child字段所有权,确保扁平化后原节点无残留子节点;

  4. borrow_mut()/drop():严格遵循借用规则,避免可变借用冲突;

  5. 模式匹配:通过if let简化Option类型的解构与判断。

lcr154

哈希表存原节点到新节点的映射

先复制节点值,再补全next和random指针

最后返回新链表头--hash val

class Solution {

public:

Node* copyRandomList(Node* head) {

if(head == nullptr) return nullptr;

Node* cur = head;

unordered_map<Node*, Node*> map;

// 3. 复制各节点,并建立 "原节点 -> 新节点" 的 Map 映射

while(cur != nullptr) {

mapcur = new Node(cur->val);

cur = cur->next;

}

cur = head;

// 4. 构建新链表的 next 和 random 指向

while(cur != nullptr) {

mapcur->next = mapcur-\>next;

mapcur->random = mapcur-\>random;

cur = cur->next;

}

// 5. 返回新链表的头节点

return maphead;

}

};

rust

把原链表节点和复制节点穿插排列,先补复制节点的random指针,再拆分出复制链表(不占额外hash空间)

// Definition for a Node.

// #derive(Debug, Clone, PartialEq, Eq)

// pub struct Node {

// pub val: i32,

// pub next: Option<Rc<RefCell<Node>>>,

// pub random: Option<Rc<RefCell<Node>>>,

// }

//

// impl Node {

// #inline

// pub fn new(val: i32) -> Self {

// Node {

// val,

// next: None,

// random: None,

// }

// }

// }

use std::rc::Rc;

use std::cell::RefCell;

impl Solution {

pub fn copy_random_list(head: Option<Rc<RefCell<Node>>>) -> Option<Rc<RefCell<Node>>> {

let mut current = head.clone();

// Step 1: Interleave copied nodes with original nodes

while let Some(node) = current {

let copied = Rc::new(RefCell::new(Node::new(node.borrow().val)));

copied.borrow_mut().next = node.borrow().next.clone();

node.borrow_mut().next = Some(copied.clone());

current = copied.borrow().next.clone();

}

// Step 2: Assign random pointers for the copied nodes

current = head.clone();

while let Some(node) = current {

if let Some(random) = node.borrow().random.clone() {

node.borrow().next.clone()?.borrow_mut().random = random.borrow().next.clone();

}

let next = node.borrow().next.clone();

current = next?.borrow().next.clone();

}

// Step 3: Separate the copied list from the original list

current = head.clone();

let new_head = head.clone()?.borrow().next.clone();

while let Some(node) = current {

let next = node.borrow().next.clone();

node.borrow_mut().next = next.clone()?.borrow().next.clone();

if let Some(node_next) = node.borrow().next.clone() {

next?.borrow_mut().next = node_next.borrow().next.clone();

}

current = node.borrow().next.clone();

}

new_head

}

}

相关推荐
吃着火锅x唱着歌12 分钟前
深度探索C++对象模型 学习笔记 第五章 构造、解构、拷贝语意学(2)
c++·笔记·学习
玖釉-14 分钟前
Vulkan 离屏渲染详解:从 Framebuffer 到后处理、阴影贴图与 Render Texture
c++·windows·计算机视觉·图形渲染
cpp_250125 分钟前
P2947 [USACO09MAR] Look Up S
数据结构·c++·算法·题解·单调栈·洛谷
楼田莉子32 分钟前
C++20新特性:协程
开发语言·c++·后端·学习·c++20
炘爚43 分钟前
phase1:基础框架——编译 + MySQL + 登录/注册
linux·c++
特种加菲猫1 小时前
C++11核心特性深度解析:从列表初始化到lambda与包装器
开发语言·c++
枕星而眠1 小时前
C++ 面向对象核心机制深度解析:多态性、虚函数、虚继承与 final 类
运维·开发语言·c++·后端
智者知已应修善业2 小时前
【51单片机8个LED,已经使用了D1D2,怎么样在不动D1D2的前提下实现D6~D8的流水灯】2024-1-19
c++·经验分享·笔记·算法·51单片机
坚果派·白晓明2 小时前
鸿蒙PC适配实战:simdjson 三方库移植攻略与 AtomCode Skills 提效之道
c++·harmonyos·三方库·skills·atomcode·c/c++三方库·c/c++三方库适配
爱装代码的小瓶子2 小时前
3. 设计buffer模块
linux·服务器·开发语言·c++·php