剑指offer-链表
1. 链表中环的入口节点
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路一:用哈希表存已经遍历过的节点,O(1)复杂度查找,如果再次遇到就是环入口
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# 用哈希表存遍历过的节点,重复的节点为环入口
if pHead is None or pHead.next is None:
return None
hashmap = set()
p = pHead
while p:
if p in hashmap:
return p
hashmap.add(p)
p = p.next
思路二:快慢指针
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# 快慢指针;如果有环,快指针会追上慢指针;再分别从头节点和快慢指针相遇点向后,相遇的节点为环入口
if pHead is None or pHead.next is None:
return None
slow = pHead
fast = pHead
while fast: # 找快慢相遇点
slow = slow.next
fast = fast.next.next
if slow == fast:
break
slow = pHead # 找环入口
while slow != fast:
slow = slow.next
fast = fast.next
return slow
2. 删除链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
思路:需要一个pre作为p的前驱节点,如果遇到重复节点就一直向后遍历到不重复的节点,pre指过去即可。再往后遍历之前需要把p退回到pre,因为后面还是有可能出现和pre重复的节点。特别注意从头节点就开始重复的情况,需要把pHead指向不重复节点。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteDuplication(self, pHead):
# write code here
if pHead is None or pHead.next is None:
return pHead
pre = None # 记录p前面的节点
p = pHead
while p:
nextp = p.next
if nextp and nextp.val == p.val: # 需要删除节点
sameVal = p.val # 向后一直找到不相同节点
pNeedDel = p
# 要么从p开始重复到最后,pNeedDel为None;要么pNeedDel指向下一个不重复的节点
while pNeedDel and pNeedDel.val == sameVal:
pNeedDel = pNeedDel.next if pre is None: # 如果pre还是None,说明从头节点开始一直重复,头节点要指向下一个不重复节点
pHead = pNeedDel
p = pHead # 继续向后遍历,pre还是None就行了
else: # 如果是从头节点后面的节点开始重复,pHead不用变
pre.next = pNeedDel # 删除从p开始的重复节点
p = pre # 要退到开始重复的上一个节点,后面可能出现与pre重复的节点 else: # 不需要删除节点,向后遍历
pre = p
p = nextp
return pHead
3. 从尾到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
思路一:递归
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
if listNode is None:
return []
if listNode.next is None: # 如果只有一个节点
return [listNode.val]
return self.printListFromTailToHead(listNode.next) + [listNode.val] # 后面所有节点值的倒序list + [当前节点值]
思路二:list保存,逆序返回
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
res = []
p = listNode
while p:
res.append(p.val)
p = p.next
return res[::-1]
思路三:利用list的操作性质
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
if listNode is None:
return []
if listNode.next is None:
return [listNode.val] res = [listNode.val]
p = listNode.next
while p:
res = [p.val] + res
p = p.next
return res
思路四:利用栈的先进后出
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
if listNode is None:
return []
if listNode.next is None:
return [listNode.val]
res = []
p = listNode
while p:
res.insert(0, p.val)
p = p.next
return res
剑指offer-链表的更多相关文章
- 剑指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的两 ...
- 剑指Offer——链表中倒数第k个节点
Question 输入一个链表,输出该链表中倒数第k个结点. Solution 一种想法就是扫描两边,第一遍求出总的节点个数,第二遍从头开始走n-k个 第二种思想类似于fast-slow指针的方法,f ...
- 剑指offer——链表相关问题总结
首先统一链表的数据结构为: struct ListNode { int val; struct ListNode *next; ListNode(int x) :val(x), next(NULL) ...
- python剑指offer 链表中环的入口节点
题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 先说个定理:两个指针一个fast.一个slow同时从一个链表的头部出发, fast一次走2步,slow一次走一步,如果该链表有环,两个指 ...
- 用js刷剑指offer(链表中倒数第k个结点)
题目描述 输入一个链表,输出该链表中倒数第k个结点. 牛客网链接 思路 设置两个指针,p,q,先让p走k-1步,然后再一起走,直到p为最后一个 时,q即为倒数第k个节点 js代码 // 空间复杂度1 ...
- 剑指offer 链表中环的入口位置
题目描述 一个链表中包含环,请找出该链表的环的入口结点. 思路:这题需要知道a = c,然后head和slow每次走一步,相遇的时候就是第一个入口交点, 注意:for循环或者while循环之后,一 ...
- 剑指offer 链表中倒数第K个节点
利用两个间隔为k的指针来实现倒数第k个 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ...
- 剑指offer——链表
#include"stdio.h" #include"stdlib.h" #include"iostream" using namespac ...
随机推荐
- scrapy实战1分布式爬取有缘网(6.22接口已挂):
直接上代码: items.py # -*- coding: utf-8 -*- # Define here the models for your scraped items # # See docu ...
- 小白开学Asp.Net Core 《七》
小白开学Asp.Net Core <七> — — 探究中间件(MiddleWare) 1.何为中间件? 中间件是组装到应用程序管道中以处理请求和响应的家伙,管道中的每个组件都要满足以下两个 ...
- [奇思异想]使用RabbitMQ实现定时任务
背景 工作中经常会有定时任务的需求,常见的做法可以使用Timer.Quartz.Hangfire等组件,这次想尝试下新的思路,使用RabbitMQ死信队列的机制来实现定时任务,同时帮助再次了解Rabb ...
- Java集合类的概述
前述 复习一下Java中的集合类,是面试笔试中常考察的一个点,特地做的整理. 什么是集合类? 集合类,也叫容器类.Java集合类可以用来存储数量庞大的对象. 我们和数组进行对比: 数组:存储基本数据类 ...
- 【深入浅出-JVM】(8):TLAB
概念 TLAB(Thread Local Allocation Buffer)线程本地分配缓冲区(线程私有分配区,私有分配,公共查看),占用 Eden 区(缺省 Eden 的1%),默认开启,JVM ...
- Spring Cloud使用Zuul网关时报错
当开启了Eureka集群后,每创建一个服务都要往这两个集群中进行注册否则访问时会产生500
- 牛客小白月赛16 E 小雨的矩阵 ( 暴搜)
链接:https://ac.nowcoder.com/acm/contest/949/E来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- Java中的Lambda表达式简介及应用
在接触Lambda表达式.了解其作用之前,首先来看一下,不用Lambda的时候我们是怎么来做事情的. 我们的需求是,创建一个动物(Animal)的列表,里面有动物的物种名,以及这种动物是否会跳,是否会 ...
- 使用SVG symbols建立图标系统完整指南
从最开始的使用img图片,到后来的使用css sprite来减少服务器请求,再到流行的图形字体化图标Iconfont.现在,一种全新的图标使用方式开始流行了起来--SVG symbols图标. 工作原 ...
- 渐进式web应用开发---promise式数据库(五)
在前面的一篇文章中,我们已经实现了使用indexedDB实现ajax本地数据存储的功能,详情,请看这篇文章.现在我们需要把上面的一篇文章中的代码使用promise结构来重构下.我们为什么需要使用pro ...