剑指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. 关于flex元素超出父元素的解决方法

    左边是label, 右边是input. 设置父级为display:flex; input为flex:1; 然后label 为 white-space: nowrap; 这时input就有可能超出父级. ...

  2. opencv对图片画框写文字

    业务背景:对图片进行画框后调用排序方法按照"从上到下,从左到右"对已经画的框进行排序.排序方法当前有缺陷,修复后需要验证. 目前有如下信息: 原始图片地址 图片对应的每个框的坐标( ...

  3. eclipse 提示错误The method of type must override a superclass method 的解决办法

    java1.5中继承接口是不需要@Override的,而在1.6以上版本中是需要添加@Override注解的,如果项目的编译器是1.5版本的就可能报错The method *** of type mu ...

  4. vue3+ts+vant制作音乐播放器(进度条拖拽、倍速切换、上一曲、下一曲)完整版

    1.进度条的用的是vant的Progress组件,比手写进度条方便很多,有自带的事件 2.H5页面兼容pc 效果展示 上代码 一.template模块 <template lang=" ...

  5. 攻防世界Web篇——PHP2

    可以从index.phps中找到网站源码 从源码中得出,要满足admin!=$_GET[id],urldecode($_GET[id]) == admin,两个条件才能得到flag 所以就将admin ...

  6. 记一次ajax文件上传

    一个新需求提交页面. 在页面提交的时候,使用的是,先上传文件再上传表单 在这里需要返回表单存储的文件地址,需要上传.所以.在上传文件之后会返回存储的地址. 这里犯的一个错误: 往input 的type ...

  7. SourceInsight4破解

    2017/10/18 更新 1. 安装原版软件:Source Insight Version 4.0.0092 -  March 20, 2018 2. 下载激活程序:sourceinsight_40 ...

  8. Flutter 新建项目

    一.打开VSCode,点击侧边栏扩展按钮,搜索flutter,安装Flutter和Dart 二.按command+shift+P,输入flutter,选择Flutter:New project,新建项 ...

  9. python字符串拼接方式

    一 .join(iterator),后面必须是可迭代对象,例如:字符串,列表,元组 testList = ["1","2"] print(",&quo ...

  10. flask中request请求中各种传参

    from flask import Flask, request from werkzeug.datastructures import FileStorage app = Flask(__name_ ...