【Leetcode】 剑指offer:链表(简单)--Day02
剑指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的更多相关文章
- LeetCode剑指Offer刷题总结(一)
LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...
- LeetCode 剑指 Offer 22. 链表中倒数第k个节点
剑指 Offer 22. 链表中倒数第k个节点 题意 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点. 例如,一个链表有 6 个 ...
- 【剑指Offer】简单部分每日五题 - Day 1
今天开始更新leetcode上<剑指Offer>的题解,先从简单难度开始.预计按下列顺序更新: 简单难度:每日5题 中等难度:每日3题 困难难度:每日1题 17 - 打印从1到最大的n位数 ...
- [leetcode] 剑指 Offer 专题(一)
又开了一个笔记专题的坑,未来一两周希望能把<剑指Offer>的题目刷完
- LeetCode—剑指 Offer学习计划
第 1 天 栈与队列(简单) 剑指 Offer 09. 用两个栈实现队列 class CQueue { public: CQueue() { } stack<int>s1,s2; void ...
- Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...
- [LeetCode]剑指 Offer 52. 两个链表的第一个公共节点
题解 nodeA走一个链表A(A独有+公共),再走B独有的长度, nodeB走一个链表B(B独有+公共),再走A独有的长度. 结果:两者相遇点即为交点:若没有交点,两者都走到null,会返回null. ...
- 剑指Offer 链表中倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 法1:设置2个指针p,q.p先移动k次,然后pq同时后移,p到链表尾尾的时候,q指向倒数第k个节点. 注意://需要考虑k=0,以 ...
- 剑指offer——链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点. class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned ...
- 剑指Offer——链表中环的入口结点
题目描述: 一个链表中包含环,请找出该链表的环的入口结点. 分析: 设置两个指针p1,p2, 两个指针都从链表的头部开始走,不过p1每次走一步,p2每次走两步. 直到相遇的时候,p2走的长度是p1的两 ...
随机推荐
- 关于flex元素超出父元素的解决方法
左边是label, 右边是input. 设置父级为display:flex; input为flex:1; 然后label 为 white-space: nowrap; 这时input就有可能超出父级. ...
- opencv对图片画框写文字
业务背景:对图片进行画框后调用排序方法按照"从上到下,从左到右"对已经画的框进行排序.排序方法当前有缺陷,修复后需要验证. 目前有如下信息: 原始图片地址 图片对应的每个框的坐标( ...
- eclipse 提示错误The method of type must override a superclass method 的解决办法
java1.5中继承接口是不需要@Override的,而在1.6以上版本中是需要添加@Override注解的,如果项目的编译器是1.5版本的就可能报错The method *** of type mu ...
- vue3+ts+vant制作音乐播放器(进度条拖拽、倍速切换、上一曲、下一曲)完整版
1.进度条的用的是vant的Progress组件,比手写进度条方便很多,有自带的事件 2.H5页面兼容pc 效果展示 上代码 一.template模块 <template lang=" ...
- 攻防世界Web篇——PHP2
可以从index.phps中找到网站源码 从源码中得出,要满足admin!=$_GET[id],urldecode($_GET[id]) == admin,两个条件才能得到flag 所以就将admin ...
- 记一次ajax文件上传
一个新需求提交页面. 在页面提交的时候,使用的是,先上传文件再上传表单 在这里需要返回表单存储的文件地址,需要上传.所以.在上传文件之后会返回存储的地址. 这里犯的一个错误: 往input 的type ...
- SourceInsight4破解
2017/10/18 更新 1. 安装原版软件:Source Insight Version 4.0.0092 - March 20, 2018 2. 下载激活程序:sourceinsight_40 ...
- Flutter 新建项目
一.打开VSCode,点击侧边栏扩展按钮,搜索flutter,安装Flutter和Dart 二.按command+shift+P,输入flutter,选择Flutter:New project,新建项 ...
- python字符串拼接方式
一 .join(iterator),后面必须是可迭代对象,例如:字符串,列表,元组 testList = ["1","2"] print(",&quo ...
- flask中request请求中各种传参
from flask import Flask, request from werkzeug.datastructures import FileStorage app = Flask(__name_ ...