剑指Offer 06. 从尾到头打印链表

可借助栈。

或先遍历列表得到元素数,开辟数组空间倒序填入。

剑指 Offer 24. 反转链表

可借助栈:

class Solution {
public ListNode reverseList(ListNode head) {
if(head == null) return null;
Deque<ListNode> d = new LinkedList<>();
ListNode cur = head;
while(cur != null) {
d.addLast(cur);
cur = cur.next;
}
ListNode nhead = d.pollLast();
cur = nhead;
while(!d.isEmpty()) {
cur.next = d.pollLast();
cur = cur.next;
}
cur.next = null;
return nhead;
}
}

双指针

双指针所定位的两个结点的指向关系要反过来,这会导致后方指针原本所指的结点丢失。因此每次双指针的移动要借助第三个指针解决结点丢失问题,使得双指针能够进行位置更新。

class Solution {
public ListNode reverseList(ListNode head) {
ListNode p1 = null, p2 = head;
while(p2 != null) {
ListNode tmp = p2.next;
p2.next = p1;
p1 = p2;
p2 = tmp;
}
return p1;
}
}

剑指 Offer 35. 复杂链表的复制

在复杂链表中,每个节点除了有一个next指针指向下一个节点,还有一个random指针指向链表中的任意节点或者null

复杂链表的复制难点在于,复制到某一结点时,该random指针所指结点可能还未被创建。所以大致有两种思路:

  • 既创建next所指结点,又创建random所指结点。
  • next所指顺序依次创建结点,全部结点创建后再开始random指针的赋值。
方法一:next结点与random结点同时递归生成

利用一Map记录结点的创建情况,若已创建则直接返回,否则创建后更新Map。由于next指针连接了所有节点,故所有节点都会被复制。

class Solution {
Map<Node, Node> createdNode = new HashMap<>();
public Node copyRandomList(Node head) {
if(head == null) return null;
Node neuu = createdNode.get(head);
if(neuu == null) {
neuu = new Node(head.val);
createdNode.put(head, neuu);
neuu.next = copyRandomList(head.next);
neuu.random = copyRandomList(head.random);
}
return neuu;
}
}
方法二:先next,后random(Map映射新旧节点)

同样采用Map记录新旧节点的对应情况。整个过程由两次针对原链表的循环组成。

第一次循环的过程除进行常规链表的复制以外,添加Map键值对,建立由原节点到新节点的映射。

第二次循环通过Map建立新节点之间的random指向关系。

class Solution {
public Node copyRandomList(Node head) {
if(head == null) return null;
Map<Node, Node> m = new HashMap<>();
Node ori = head, last = null;
while(ori != null) {
m.put(ori, new Node(ori.val));
if(ori != head) {
m.get(last).next = m.get(ori);
}
last = ori;
ori = ori.next;
}
m.get(last).next = null; ori = head;
while(ori != null) {
if(ori.random != null) {
m.get(ori).random = m.get(ori.random);
}
else {
m.get(ori).random = null;
}
ori = ori.next;
}
return m.get(head);
}
}
方法三:先next,后random(新节点暂时插入原节点后)

方法二与方法三并无本质区别,对random指针赋值的基础都是新旧相应结点的映射。

方法二主要由三次链表的遍历组成:

第一次遍历,按照原链表next顺序依次创建新节点,并将新节点插入原链表对应旧结点后,使原链表的长度翻倍。这样做的意义是实现了通过旧结点的next指针访问对应新结点,且原列表的next顺序也没有丢失。

第二次遍历,复制random关系。这一遍历的循环变量仍然会依次被赋值为原链表的各节点,假设某一时刻循环变量指向结点A。则A.next指向新节点,A.random指向原节点的random目标,A.random.next指向新节点random指针待指向的节点。

第三次遍历,将新旧链表分离。

class Solution {
public Node copyRandomList(Node head) {
if(head == null) return null;
for(Node ori = head; ori != null; ori = ori.next.next) {
Node neuu = new Node(ori.val);
neuu.next = ori.next;
ori.next = neuu;
}
for(Node ori = head; ori != null; ori = ori.next.next) {
Node neuu = ori.next;
neuu.random = (ori.random == null)?null:(ori.random.next);
}
Node nhead = head.next;
for(Node ori = head; ori != null; ori = ori.next) {
Node neuu = ori.next;
ori.next = neuu.next;
if(neuu.next != null) neuu.next = neuu.next.next;
}
return nhead;
}
}

【Leetcode】 剑指offer:链表(简单)--Day02的更多相关文章

  1. LeetCode剑指Offer刷题总结(一)

    LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...

  2. LeetCode 剑指 Offer 22. 链表中倒数第k个节点

    剑指 Offer 22. 链表中倒数第k个节点 题意 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点. ​ 例如,一个链表有 6 个 ...

  3. 【剑指Offer】简单部分每日五题 - Day 1

    今天开始更新leetcode上<剑指Offer>的题解,先从简单难度开始.预计按下列顺序更新: 简单难度:每日5题 中等难度:每日3题 困难难度:每日1题 17 - 打印从1到最大的n位数 ...

  4. [leetcode] 剑指 Offer 专题(一)

    又开了一个笔记专题的坑,未来一两周希望能把<剑指Offer>的题目刷完

  5. LeetCode—剑指 Offer学习计划

    第 1 天 栈与队列(简单) 剑指 Offer 09. 用两个栈实现队列 class CQueue { public: CQueue() { } stack<int>s1,s2; void ...

  6. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

  7. [LeetCode]剑指 Offer 52. 两个链表的第一个公共节点

    题解 nodeA走一个链表A(A独有+公共),再走B独有的长度, nodeB走一个链表B(B独有+公共),再走A独有的长度. 结果:两者相遇点即为交点:若没有交点,两者都走到null,会返回null. ...

  8. 剑指Offer 链表中倒数第k个结点

    题目描述 输入一个链表,输出该链表中倒数第k个结点.     思路: 法1:设置2个指针p,q.p先移动k次,然后pq同时后移,p到链表尾尾的时候,q指向倒数第k个节点. 注意://需要考虑k=0,以 ...

  9. 剑指offer——链表中倒数第k个结点

    输入一个链表,输出该链表中倒数第k个结点. class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned ...

  10. 剑指Offer——链表中环的入口结点

    题目描述: 一个链表中包含环,请找出该链表的环的入口结点. 分析: 设置两个指针p1,p2, 两个指针都从链表的头部开始走,不过p1每次走一步,p2每次走两步. 直到相遇的时候,p2走的长度是p1的两 ...

随机推荐

  1. 什么时候用多线程什么时候用多进程呢?GUL

    那么在 Python 中什么时候用多线程什么时候用多进程呢?当在CPU-bound(计算密集型:绝大多数时间在计算) 时最好用 - 多进程, 而在 I/O bound(I/O密集型 : IO 处理 并 ...

  2. 钉钉机器人webhook的使用

    1.群启动webhook机器人:右上角设置--智能助手---添加机器人---其他机器人 2.获取webhook地址 3.调用方式不一样,则访问方式就不一样 ---------------------- ...

  3. 光纤加速计算 383-高速信号处理板 XCKU060的双路QSFP+光纤PCIe 卡 XCKU060板卡

    基于kintex UltraScale XCKU060的双路QSFP+光纤PCIe 卡 一.板卡概述 本板卡系北京太速科技自主研发,基于Xilinx UltraScale Kintex系列FPGA   ...

  4. js - script标签的for属性和event属性

    js - script标签的for属性和event属性 <script language="javascript" for="window" event= ...

  5. 源码安装pg9.6

    源码安装pg9.6 添加用户 useradd pg96 下载源码包 wget https://ftp.postgresql.org/pub/source/v9.6.24/postgresql-9.6. ...

  6. 使用powerdesigner连接MySQL并设置逆向工程

    使用powerdesigner连接MySQL并设置逆向工程 环境:powerdesigner15.1 MySQL5.7 win10 X64 1.安装mysql-connector-odbc-5.3.8 ...

  7. linux修改网络

    如何修改ip 临时方法: ifconfig DIVICE IP netmask NETMASK 知识临时修改ip,重启或重启网络恢复 在一个网卡上设置多个ip ifconfig DEVICE:NUMB ...

  8. ffmpeg编译错误/libfdk-aacenc.c: In function 'aac_encode_init'

    ffmpeg编译错误/libfdk-aacenc.c: In function 'aac_encode_init' 需要手动打一个补丁 https://git.libav.org/?p=libav.g ...

  9. phpmyadmin scripts/setup.php 反序列化漏洞(WooYun-2016-199433)(Kali)

    ​ phpmyadmin 2.x版本中存在一处反序列化漏洞,通过该漏洞,攻击者可以读取任意文件或执行任意代码. 通过vulhub靶场进行复现操作 1.首先搭建靶场环境(采用Kali) cd vulhu ...

  10. Vue 二维码生成插件

    1. 安装 qrcode.vue 仓库地址 // vue2 安装1.x版本.vue3 安装3.x版本 npm install --save qrcode.vue // 或 yarn add qrcod ...