移除链表元素&反转链表&设计链表
一、移除链表元素
1.方法概述
带傀儡节点的方法:
- 创建一个傀儡节点puppet来充当该链表的假头节点,当真正的头结点head不为null时,且在真正的头节点head的val值在等于删除值val时进行删除操作的方式则与后面与删除值val相等的节点的删除方法一致。删除完后返回傀儡节点puppet的next域指向的节点即可。
不带傀儡节点的方法:
- 不带傀儡节点,当真正的头结点head不为null时,就需要考虑头节点的val值是否等于删除值val,如果等于则需要将head指向head的next域所指的节点,也就是向后挪一个节点达到删除的目的。再进行删除操作。最后返回头节点即可。
2.具体实现
Java版本实现带傀儡节点的方法:
点击查看代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head;
}
ListNode puppet = new ListNode(-1, head);
ListNode pre = puppet;
ListNode cur = head;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return puppet.next;
}
}
Java版本实现不带傀儡节点的方法:
点击查看代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
while(head != null && head.val == val){
head = head.next;
}
if (head == null) {
return head;
}
ListNode prev = head;
ListNode cur = head.next;
while (cur != null) {
if(cur.val == val){
prev.next = cur.next;
}else{
prev = cur;
}
cur = cur.next;
}
return head;
}
}
3.要点总结
- 是否带傀儡节点。
- 删除的位置是否为头节点head,如果节点的val值为删除值val,该是如何移动,否则该如何移动。
- 该如何删除。
二、反转链表
1.方法概述
- 将头节点之后的节点用头插法的方式进行反转。

三个引用方法:
- 定义三个引用,分别记录当前节点cur和当前节点的前驱prev,当前节点的后继curNext。然后进行反转。

递归方法:
- 设计一个反转函数,使用递归的方式来调用反转函数进行反转。
2.具体实现
头插方法
点击查看代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null){
return null;
}
if(head.next == null){
return head;
}
ListNode cur = head;
ListNode curNext = cur.next;
cur.next = null;
cur = curNext;
while(cur != null){
curNext = cur.next;
cur.next = head;
head = cur;
cur = curNext;
}
return head;
}
}
三个引用
点击查看代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
ListNode newHead = null;
while(cur != null){
ListNode curNext = cur.next;
if(curNext == null){
newHead = cur;
}
cur.next = prev;
prev = cur;
cur = curNext;
}
return newHead;
}
}
递归
从前往后递归
点击查看代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverse(ListNode prev,ListNode cur){
if(cur == null){
return prev;
}
ListNode curNext = null;
curNext = cur.next;
cur.next = prev;
return reverse(cur,curNext);
}
public ListNode reverseList(ListNode head) {
return reverse(null,head);
}
}
从后往前递归
点击查看代码
class Solution {
ListNode reverseList(ListNode head) {
// 边缘条件判断
if(head == null) return null;
if (head.next == null) return head;
// 递归调用,翻转第二个节点开始往后的链表
ListNode last = reverseList(head.next);
// 翻转头节点与第二个节点的指向
head.next.next = head;
// 此时的 head 节点为尾节点,next 需要指向 NULL
head.next = null;
return last;
}
}
3.要点总结
头插法:
- 需要注意的是原本链表就为null的情况,直接返回null。
- 当链表只有一个节点的情况下直接返回头节点head。
- 在反转时需要有curNext引用来记录cur的下一个节点位置。以防cur的next域被修改后找不到下一节点。
三个引用:
- 当cur为null时循环反转操作停止,prev所指向的就是新的头节点newHead。
递归:
- 一个方法在执行过程中调用自身就称为递归,递归的关键在于一定要有一个趋近于终止的条件,否则会出现栈溢出异常的错误!本题的递归趋近条件就是当cur == null,也就是所有节点反转完成后,引用到达的边界条件。
三、设计链表
2.具体实现
点击查看代码
class ListNode{
int val;
ListNode next,prev;
ListNode() {};
ListNode(int val){
this.val = val;
}
}
class MyLinkedList {
int size;
ListNode head,tail;
public MyLinkedList() {
this.size = 0;
this.head = new ListNode(0);
this.tail = new ListNode(0);
head.next=tail;
tail.prev=head;
}
public int get(int index) {
if(index<0 || index>=size){
return -1;
}
ListNode cur = this.head;
if(index >= size / 2){
cur = tail;
for(int i=0; i< size-index; i++){
cur = cur.prev;
}
}else{
for(int i=0; i<= index; i++){
cur = cur.next;
}
}
return cur.val;
}
public void addAtHead(int val) {
addAtIndex(0,val);
}
public void addAtTail(int val) {
addAtIndex(size,val);
}
public void addAtIndex(int index, int val) {
if(index>size){
return;
}
if(index<0){
index = 0;
}
size++;
ListNode pre = this.head;
for(int i=0; i<index; i++){
pre = pre.next;
}
ListNode newNode = new ListNode(val);
newNode.next = pre.next;
pre.next.prev = newNode;
newNode.prev = pre;
pre.next = newNode;
}
public void deleteAtIndex(int index) {
if(index<0 || index>=size){
return;
}
size--;
ListNode pre = this.head;
for(int i=0; i<index; i++){
pre = pre.next;
}
pre.next.next.prev = pre;
pre.next = pre.next.next;
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
未完待续...
移除链表元素&反转链表&设计链表的更多相关文章
- [LeetCode] Remove Linked List Elements 移除链表元素
Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 -- ...
- Leecode刷题之旅-C语言/python-203移除链表元素
/* * @lc app=leetcode.cn id=203 lang=c * * [203] 移除链表元素 * * https://leetcode-cn.com/problems/remove- ...
- [LeetCode] 203. Remove Linked List Elements 移除链表元素
Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...
- Java实现 LeetCode 203 移除链表元素
203. 移除链表元素 删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2 ...
- [LeetCode] 203. 移除链表元素(链表基本操作-删除)、876. 链表的中间结点(链表基本操作-找中间结点)
题目 203. 移除链表元素 删除链表中等于给定值 val 的所有节点. 题解 删除结点:要注意虚拟头节点. 代码 class Solution { public ListNode removeEle ...
- 【LeetCode】203.移除链表元素
203.移除链表元素 知识点:链表:双指针 题目描述 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 . 示例 ...
- LeetCode 203. Remove Linked List Elements 移除链表元素 C++/Java
Remove all elements from a linked list of integers that have value val. Example: Input: ->->-& ...
- C语言移除链表元素
删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4 ...
- [Swift]LeetCode707. 设计链表 | Design Linked List
Design your implementation of the linked list. You can choose to use the singly linked list or the d ...
- 链表回文判断(基于链表反转)—Java实现
学习数据结构的时候遇到一个经典的回文链表问题 对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构. 如果有链表反转的基础,实现链表回文判断就简单的多,如 ...
随机推荐
- uniapp 实现小程序中自定义tabBar 的方法
uniapp 实现小程序中自定义tabBar 的方法 第一种方式: page.json中配置 "tabBar": { "color": "#7A7E8 ...
- 深度学习之tensorflow2实战:多输出模型
欢迎来到CNN实战,尽管我们刚刚开始,但还是要往前看!让我们开始吧! 数据集 链接:https://pan.baidu.com/s/1zztS32iuNynepLq7jiF6RA 提取码:ilxh,请 ...
- Crony 一个基于Go语言实现的分布式定时任务管理平台
crony - 分布式定时任务管理平台 1. 基本介绍 1.1 项目背景 项目中存在许多定时任务,很多代码写法都是采取见缝插针式的写法或者直接丢到task服务里面写,存在以下问题 服务多实例时执行定时 ...
- vs同步配置
做法(整个流程的过程):1.安装插件2.在GitHub上生成token3.获取gistid4.使用2,3步生成的token和gistid 1.在vscode上安装 settings sync 插件(我 ...
- 小米mini路由器刷breed不死鸟和潘多拉固件
前言 开启小米路由器ssh, 这一步浪费我很长时间,因为目前的开发版都对ssh升级进行了md5校验,导致官方升级方法总是失败,所以换成老版本的 路由器固件就行了. 步骤 下载 0.4.36 mini路 ...
- TypeError: Object(…) is not a function
vue中遇到的这个错误 1. 先检查变量名或者函数名是否有重复定义 报这错之后看了好久,也没有发现starkflow上说的,重复定义了变量或者函数 2. vue的话 检查下函数写的位置,直接写到cre ...
- v-model双向绑定原理
1 <div id="app"> 2 <div>{{msg}}</div> 3 <!-- 写法1 --> 4 <input t ...
- ATM购物车项目 三层架构
目录 项目开发流程 项目需求 三层架构 (重点) 实际案例 展示层 核心逻辑层 数据处理层 ATM项目 项目开发流程 # 1.项目需求分析 产品经理(客户) 架构师 开发经理 1.架构师 开发经理提前 ...
- SQLMap入门——查询当前用户下的所有数据库
确定网站存在注入后,用于查询当前用户下的所有数据库 python sqlmap.py -u http://localhost/sqli-labs-master/Less-1/?id=1 --dbs
- kali安装拼音输入法
前言 最近使用kali感觉没个中文输入法的很不方便,于是决定装个ibus的拼音输入法 安装方法 1.安装ibus 使用命令apt install ibus ibus-pinyin,注意使用root权限 ...