430. Flatten a Multilevel Doubly Linked List(扁平化多级双向链表)

本文介绍了一种将多级双向链表扁平化为单级双向链表的算法,通过三种方法实现:迭代、两种不同的递归方法。算法核心在于处理含有子链表的节点,将子链表融合进主线链表中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表。这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。
扁平化列表,使所有结点出现在单级双链表中。您将获得列表第一级的头部。
示例:

输入:
1—2---3—4---5—6–NULL
|
7—8---9—10–NULL
|
11–12–NULL

输出:
1-2-3-7-8-11-12-9-10-4-5-6-NULL

以上示例的说明:

给出以下多级双向链表:
在这里插入图片描述我们应该返回如下所示的扁平双向链表:

在这里插入图片描述

方法思路

Approach1:
Basic idea is straight forward:
1.Start form the head , move one step each time to the next node
2.When meet with a node with child, say node p, follow its child chain to the end and connect the tail node with p.next, by doing this we merged the child chain back to the main thread。
3.Return to p and proceed until find next node with child.
4.Repeat until reach null

class Solution {
    //Runtime: 1 ms, faster than 100.00%
    //Memory Usage: 37.5 MB, less than 26.05%
    public Node flatten(Node head) {
        if( head == null) return head;
	    // Pointer
        Node p = head; 
        while( p!= null) {
            // CASE 1: if no child, proceed
            if( p.child == null ) {
                p = p.next;
                continue;
                //continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代
                //在 for 循环中,continue 语句使程序立即跳转到更新语句
                //在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句
            }
            // CASE 2: got child, find the tail of the child and link it to p.next 
            Node temp = p.child;
            // Find the tail of the child
            while( temp.next != null ) 
                temp = temp.next;
            // Connect tail with p.next, if it is not null
            temp.next = p.next;  
            if( p.next != null )  p.next.prev = temp;
            // Connect p with p.child, and remove p.child
            p.next = p.child; 
            p.child.prev = p;
            p.child = null;
        }
        return head;
    }
}

Approach2: recursive

第一种递归方法:

class Solution{
    //Runtime: 1 ms, faster than 100.00%
    //Memory Usage: 36.4 MB, less than 85.29% 
    Node pre = null;
    public Node flatten(Node head) {
        flattenHelper(head);
        return head;
    }
    public void flattenHelper (Node head){
        if(head == null) return;
        Node post = head.next;
        Node child = head.child;
        if(pre != null){
            pre.next = head;
            head.prev = pre;
            pre.child = null;
        }
        pre = head;
        flattenHelper(child);
        flattenHelper(post);
    }
}

第二种递归方法:

class Solution{
    public Node flatten(Node head) {
    	flattentail(head);
    	return head;
    }

    // flattentail: flatten the node "head" and return the tail in its child (if exists)
    // the tail means the last node after flattening "head"

    // Five situations:
    // 1. null - no need to flatten, just return it
    // 2. no child, no next - no need to flatten, it is the last element, just return it
    // 3. no child, next - no need to flatten, go next
    // 4. child, no next - flatten the child and done
    // 5. child, next - flatten the child, connect it with the next, go next
    //Runtime: 1 ms, faster than 100.00%
    //Memory Usage: 36.5 MB, less than 82.35%
    private Node flattentail(Node head) {
    	if (head == null) return head; // CASE 1
    	if (head.child == null) {
    		if (head.next == null) return head; // CASE 2
    		return flattentail(head.next); // CASE 3
    	}
    	else {
    		Node child = head.child;  
    		head.child = null;
    		Node next = head.next;
    		Node childtail = flattentail(child);
    		head.next = child;
    		child.prev = head;  
			if (next != null) { // CASE 5
				childtail.next = next;
				next.prev = childtail;
				return flattentail(next);
			}
            return childtail; // CASE 4
    	}	   	
    }
}
<think>我们正在解决关于`img2.flatten().tolist()`的使用方法和常见问题用户之前的问题涉及到了图像处理(引用[2])和词云(引用[3])中的flatten操作,因此我们可以推测用户可能是在处理图像数据或类似的多维数组用户当前问题:我想解决img2.flatten().tolist()相关的Python代码问题请问Pythonimg2flattentolist使用方法及常见问题重点解释:1.img2是什么?通常是一个numpy数组(图像处理中常用)2.flatten()的作用:将多维数组转换为一维数组(向量)3.tolist()的作用:将numpy数组转换为Python原生列表使用场景:-当需要将图像数据转换成一维列表以便于处理(如传递给某些需要列表的API)-在机器学习中,将图像展平作为特征向量-在数据可视化中,有时也需要展平数据步骤:1.确保img2是一个numpy数组(通常通过OpenCV、PIL等库读取图像得到)2.调用flatten()方法得到一维数组3.调用tolist()方法将numpy数组转换为Python列表示例代码:```pythonimportcv2#读取图像img=cv2.imread('example.jpg')#假设img是一个三维数组(高度,宽度,通道数)#使用flatten和tolistflattened_list=img.flatten().tolist()#现在flattened_list是一个一维列表,包含了图像的所有像素值(按行主序,通道顺序为BGR)```常见问题:1.数组类型问题:如果img2不是numpy数组,可能没有flatten()方法。需要先转换为numpy数组。2.内存问题:对于大图像,展平后的列表会很大,可能导致内存不足。3.性能问题:tolist()对于大数组可能较慢。4.数据顺序:flatten()默认按行主序(C风格)展平,如果需要按列主序(Fortran风格),可以使用flatten('F')。5.多通道图像:对于彩色图像,展平后是每个像素的多个通道值连续排列。替代方案(如果需要节省内存):-使用迭代器或生成器,避免一次性生成整个列表-使用numpy数组的视图(view)或迭代注意事项:-展平后的列表丢失了原始图像的结构信息(尺寸、通道数),因此在需要恢复图像时必须记录原始形状。恢复图像(如果需要):```python#假设原图像形状为(rows,cols,channels)importnumpyasnp#将列表转回numpy数组arr=np.array(flattened_list)#重新塑形img_restored=arr.reshape(rows,cols,channels)```生成相关问题:1.如何将展平后的图像列表恢复为多维数组?2.展平操作对图像处理有什么影响?3.除了tolist(),还有其他方法将numpy数组转换为Python原生数据类型吗?4.在处理大图像时,如何避免flatten和tolist导致的内存问题?</think> ### `img2.flatten().tolist()` 使用详解 #### 1. **核心功能说明** - `img2.flatten()`: 将多维图像数组压缩为一维向量 - 输入:如 `(28,28)` 的灰度图 → 输出 `(784,)` 的向量 - 输入:如 `(256,256,3)` 的RGB图 → 输出 `(196608,)` 的向量 - `.tolist()`: 将NumPy数组转为Python原生列表 - 转换前:`np.array([1,2,3])` - 转换后:`[1, 2, 3]` - **适用场景**: - 机器学习数据预处理(如输入全连接网络) - 保存/传输图像数据 - 跨库兼容(如从OpenCV转TensorFlow) #### 2. **标准使用方法** ```python import cv2 import numpy as np # 示例图像 (100x100 RGB) img2 = cv2.imread("image.jpg") # 返回形状 (100, 100, 3) # 展平并转换 flatten_list = img2.flatten().tolist() print(type(flatten_list)) # <class 'list'> print(len(flatten_list)) # 30000 (100*100*3) print(flatten_list[:5]) # 示例: [82, 45, 119, ...] ``` #### 3. **常见问题解决** ##### 问题1:数据类型不匹配错误 ```python # 错误示例: 非数组对象 text_data = [120, 80, 200] result = text_data.flatten().tolist() # AttributeError! # ✅ 解决方案:先转为NumPy数组 import numpy as np fixed_list = np.array(text_data).flatten().tolist() ``` ##### 问题2:内存溢出 (大图像处理) ```python # 4K图像 (3840x2160x3) ≈ 24.9MB img_large = cv2.imread("4k_image.jpg") # ❌ 直接操作会导致内存溢出 # flatten_list = img_large.flatten().tolist() # ✅ 解决方案:分批处理 batch_size = 1000000 flatten_batches = [] for i in range(0, img_large.size, batch_size): batch = img_large.flatten()[i:i+batch_size].tolist() flatten_batches.extend(batch) ``` ##### 问题3:通道顺序错误 (OpenCV特有) ```python img_bgr = cv2.imread("image.jpg") # 默认BGR通道 # 错误的数据顺序: [B0, G0, R0, B1, ...] flatten_list = img_bgr.flatten().tolist() # ✅ 解决方案:转换为RGB后再处理 img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) correct_list = img_rgb.flatten().tolist() # [R0, G0, B0, ...] ``` #### 4. **性能优化建议** 1. **避免重复转换**: ```python # ❌ 低效方式 (两次转换) arr = img2.flatten() lst = arr.tolist() # ✅ 高效方式 (链式操作) lst = img2.flatten().tolist() ``` 2. **需要索引时保留数组格式**: ```python # 仅需少量元素时 sample = img2.flatten()[:100].tolist() # 先切片再转换 ``` 3. **使用视图(view)避免复制**: ```python arr_view = img2.reshape(-1) # 创建视图(无内存复制) lst_view = arr_view.tolist() # 实际转换时才复制 ``` #### 5. **典型应用场景** 1. **机器学习数据准备**: ```python # MNIST分类任务 from tensorflow.keras.datasets import mnist (train_images, _), (_, _) = mnist.load_data() flattened_data = [img.flatten().tolist() for img in train_images[:1000]] ``` 2. **图像序列化存储**: ```python import json serialized = json.dumps(flattened_list) # 存储为JSON ``` 3. **可视化像素分布**: ```python import matplotlib.pyplot as plt plt.hist(img2.flatten().tolist(), bins=256) plt.title("Pixel Value Distribution") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值