算法修炼之路——【链表】Leetcode24 两两交换链表中的节点
题目描述
给定一单链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是简单的改变节点内部的值,而是需要实际的进行节点交换。
示例:
输入:head = [1, 2, 3, 4]
输出:head = [2, 1, 4, 3]
解题思路
我们通过示例可以简单了解到,需要两两进行位置互换,但是互换的动作需要涉及到前置节点与后置节点。这里为方便理解,我们先单独给出四个节点:

图1
见图1所示,我们在T1时刻交换[1, 2]两个节点,T2时刻交换[3, 4]。
这里易看出,此问题可以解为:
- 两两交换
- 迭代两两交换
对于问题1:
我们将总体链表的两两交换位置分别为若干相同的问题1,解法则有:
/*
head = [1, 2, 3, 4]
first, focus [1, 2]
*/
ListNode currHead; // and currHead.next = left leftP.next = rightP.next; // 1->2->3 changed to 1->3
right.next = leftP; // 1->3 changed to 2->1->3
currHead.next = rightP; //upgrate head of piece of this pair
这里涉及到的额外节点信息是两个节点组的前置节点,即currHead;当我们交换[3, 4]时则有:
/*
head = [2, 1, 3, 4]
secod, focus [3, 4] leftP point to 3, rightP 4.
*/
// currHead.next = leftP, here, currHead = ListNode(1) // exchange node 3 and 4
leftP.next = rightP.next;
rightP.next = leftP;
currHead.next = rightP;
对于问题2:
截止到这里,我们已经探索到了问题1的解法,接下来需要做的就是将填补问题1间的缝隙,即将他们融合为一个整体,这里我们容易理解,在交换[3, 4]的时候,需要用到交换[1,2]后的靠后节点(这里为ListNode(1)),则可以理解我们在两两交换时,统一的需要用到currHead, 即两个节点[a, b]中 靠前节点a的前置节点,并需要在[a, b]交换位置后为下一对即将交换的节点更新它们所需的currHead。则我们可以将前两部分代码融合为:
ListNode leftP = head;
ListNode rightP = head.next; ListNode currHead = dummyHead; //for head node // iteration
leftP.next = rightP.next;
rightP.next = leftP;
currHead.next = rightP; //update pos of currHead
currHead = leftP;
步骤罗列
我们已经对问题的解答有了核心的理解,这里将步骤进行进一步梳理:
- 初始化两个指针,一左一右;且为统一规则,采取哨兵机制;
- 迭代:节点交换,并更新下一对节点的靠前前置节点;
- 迭代终止条件为两指针均不为空;终止后返回哨兵节点的下一节点。
解题代码
public static ListNode solutionWithTwoP(ListNode head) {
if (head == null || head.next == null) {
return head;
}
//1. init pointers and dummyHead
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode leftP = head;
ListNode rightP = head.next;
ListNode currHead = dummyHead;
//2. iteration
while (leftP != null && rightP != null) {
// exchange
leftP.next = rightP.next;
rightP.next = leftP;
currHead.next = rightP;
//update pos of currHead
currHead = leftP;
//move forward
leftP = leftP.next;
rightP = leftP == null? null : leftP.next; //attention here
}
return dummyHead.next;
}
复杂度分析
时间复杂度:我们对数据仅进行了一次遍历,所以时间复杂度为O(N);
空间复杂度:我们没有借助额外的容器,所以空间复杂度为常量级O(1)。
GitHub源码
完整可运行文件请访问GitHub。
算法修炼之路——【链表】Leetcode24 两两交换链表中的节点的更多相关文章
- 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II
[算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...
- [Swift]LeetCode24. 两两交换链表中的节点 | Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head. Example: Given 1->2->3 ...
- LeetCode初级算法--链表02:合并两个有序链表
LeetCode初级算法--链表02:合并两个有序链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...
- python经典面试算法题1.3:如何计算两个单链表所代表的数之和
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.2 如何实现链表的逆序 [华为笔试题] 难度系数:⭐⭐⭐ ...
- 算法练习之合并两个有序链表, 删除排序数组中的重复项,移除元素,实现strStr(),搜索插入位置,无重复字符的最长子串
最近在学习java,但是对于数据操作那部分还是不熟悉 因此决定找几个简单的算法写,用php和java分别实现 1.合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两 ...
- Leetcode24.Swap Nodes in Pairs两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 说明: 你的算法只能使用常数的 ...
- LeetCode24 两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 说明: 你的算法只能使用常数的 ...
- Leetcode算法系列(链表)之两数相加
Leetcode算法系列(链表)之两数相加 难度:中等给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字.如果,我们将 ...
- [PHP] 算法-合并两个有序链表为一个有序链表的PHP实现
合并两个有序的链表为一个有序的链表: 类似归并排序中合并两个数组的部分 1.遍历链表1和链表2,比较链表1和2中的元素大小 2.如果链表1结点大于链表2的结点,该结点放入第三方链表 3.链表1往下走一 ...
随机推荐
- scrapy post payload的坑及相关知识的补充【POST传参方式的说明及scrapy和requests实现】
一.问题及解决: 在用scrapy发送post请求时,把发送方式弄错了. 本来应该是 application/x-www-form-urlencoded 弄成了application/json. 但 ...
- 身为 Java 程序员必须掌握的 10 款开源工具!
本文主要介绍Java程序员应该在Java学习过程中的一些基本和高级工具.如果你是一位经验丰富的Java开发人员,你可能对这些工具很熟悉,但如果不是,现在就是是开始学习这些工具的好时机.Java世界中存 ...
- 【30分钟学完】canvas动画|游戏基础(6):坐标旋转探究
前言 本篇主要讲坐标旋转及其应用,这是编程动画必不可少的技术. 阅读本篇前请先打好前面的基础. 本人能力有限,欢迎牛人共同讨论,批评指正. 坐标旋转 模拟场景:已知一个中心点(centerX,cent ...
- 在浏览器中使用ES6的模块功能 import 及 export
感谢英文原作者 Jake Archibald 的技术分享 各个浏览器对于ES6模块 import . export的支持情况 Safari 10.1. Chrome 61. Firefox 54 – ...
- 2019年最新老男孩高性能Web架构与自动化运维架构视频教程
课程目录L001-老男孩架构15期-Web架构之单机时代L002-老男孩架构15期-Web架构之集群时代L003-老男孩架构15期-Web架构之dnsL004-老男孩架构15期-Web架构之缓存体系L ...
- 三维GIS引擎地图可视化渲染方案设计
1.GIS地图可视化流程 GIS地图可视化就是将空间数据转化为地图数据再进行交互处理的方法,下图一展示了地图可视化的可编程渲染的典型管道,原始空间数据必须处理为图形API支持基础图元用以地图渲染.下图 ...
- unzip详解,Linux系统如何解压缩zip文件?
通常在使用linux时会自带了unzip,但是在最小化安装之后,可能系统里就无法使用此命令了. yum list unzip 查看是否安装 如果没安装过就继续 yum install unzip 安装 ...
- 编译 AR9271 wifi 网卡固件 htc_9271.fw
下载最新的固件源码https://github.com/qca/open-ath9k-htc-firmware/archive/1.4.0.zip得到 open-ath9k-htc-firmware- ...
- leetcode面试题42. 连续子数组的最大和
总结一道leetcode上的高频题,反反复复遇到了好多次,特别适合作为一道动态规划入门题,本文将详细的从读题开始,介绍解题思路. 题目描述示例动态规划分析代码结果 题目 面试题42. 连续子数 ...
- Python面向对象之:类空间问题以及类之间的关系
一. 类的空间问题 1.1 何处可以添加对象属性 class A: def __init__(self,name): self.name = name def func(self,sex): se ...