每天AC系列(十):两两交换链表中的节点

1 题目

LeetCode第24题,交换链表的相邻节点.

2 直接交换

直接交换的思想很简单,遍历一次链表,进行两两交换.

ListNode newHead = new ListNode(0);
newHead.next = head;
ListNode before = newHead;
ListNode first = head;
ListNode second = head.next;
ListNode move;

while(true)
{
    move = second.next;
    first.next = second.next;
    second.next = first;

    before.next = second;
    before = first;

    first = move;

    if(move != null && move.next != null)
    {
        second = move.next;
        move = move.next.next;
    }
    else
        break;
}
return newHead.next;

虽然思想简单,但是,并不好实现,有点绕,首先增加一个头节点,first,second当前要交换的两个节点,before为first的前一个节点,用来连上first,move是为了更新first与second节点的节点,进入while循环后,首先把first与second交换,接着用before连上first同时更新before,然后利用move更新first与second.

3 递归交换

递归交换就是每次只交换头两个节点,然后把第三个节点作为下一次递归交换的头结点继续递归交换.

if(head != null && head.next != null)
{
    ListNode t = head.next;
    head.next = swapPairs(t.next);
    t.next = head;
    return t;
}
return head;

要注意交换的顺序,先赋值head.next,head.next为剩下的节点,然后把t连上head.

4 插入法

新建一个链表,采用尾插法,依次插入交换的节点.
对于原链表设置两个指针a与b,令a指向首个节点,b指向第二个节点,然后对于新链表,先插入b,再插入a,最后更新a,b,使a,b都指向后继的后继,这样依次插入b与a就会得到所需的链表.

if(head == null || head.next == null)
    return head;
ListNode a = head;
ListNode b = head.next;
ListNode newHead = new ListNode(0);
ListNode t = newHead;
while(a != null && b != null)
{
    t.next = new ListNode(b.val);
    t = t.next;
    t.next = new ListNode(a.val);
    t = t.next;
    if(b.next != null)
        b = b.next.next;
    a = a.next.next;
}
if(a != null)
    t.next = new ListNode(a.val);
return newHead.next;

在更新a,b时,对于a不需要判断a.next是否为空,因为a.next肯定为b,肯定不为空,但是对于b,当到达最后一个节点时,b.next为空,因此需要加上判断.当a,b其中一个为空后跳出循环,最后的判断a是否为空表示节点个数为奇数,此时a指向最后一个节点,直接插入a.

5 插入法改进

对于上面的插入法,由于ab是连在一起的,因此可以只使用其中一个,再优化判空与插入操作.

ListNode newHead = new ListNode(0);
ListNode t = newHead;
while(head != null)
{
    if(head.next != null)
    {
        t.next = new ListNode(head.next.val);
        t = t.next;
    }
    t.next = new ListNode(head.val);
    t = t.next;
    if(head.next == null)
        break;
    head = head.next.next;
}
return newHead.next;

要注意while中的判空条件,因为节点的个数有可能是奇数,在插入后一个节点前需要先判断是否为空,再插入前一个节点.

6 源码

github

码云

原文地址:https://blog.51cto.com/14415843/2468678

时间: 2024-10-01 02:47:43

每天AC系列(十):两两交换链表中的节点的相关文章

【leetcode 简单】 第六十九题 删除链表中的节点

请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点. 现有一个链表 -- head = [4,5,1,9],它可以表示为: 4 -> 5 -> 1 -> 9 示例 1: 输入: head = [4,5,1,9], node = 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 示例 2: 输入: head = [4,5,1,9], node = 1 输

451 两两交换链表中的节点

原题网址:https://www.lintcode.com/problem/swap-nodes-in-pairs/description 描述 给一个链表,两两交换其中的节点,然后返回交换后的链表. 您在真实的面试中是否遇到过这个题?  是 样例 给出 1->2->3->4, 你应该返回的链表是 2->1->4->3. 挑战 你的算法只能使用常数的额外空间,并且不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 标签 链表 思路:要形成一个新链表,主要操作就

LintCode Python 简单级题目 451.两两交换链表中的节点

题目描述: 给一个链表,两两交换其中的节点,然后返回交换后的链表. 您在真实的面试中是否遇到过这个题? Yes 样例 给出 1->2->3->4, 你应该返回的链表是 2->1->4->3. 挑战 你的算法只能使用常数的额外空间,并且不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 标签 链表 题目分析: 你的算法只能使用常数的额外空间,即不能新建链表: 并且不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 创建三个指针: head指向开始交换的

LintCode之两两交换链表中的节点

题目描述: 我的思路: 由题目描述可知,题目是要求将第一个与第二个节点,第三个与第四节点....进行交换,而进行交换时只用将节点的值进行交换即可.需要注意的是:当链表为null或者当链表只有一个节点时就没有可进行交换的另一个节点,就可以直接将该链表返回. 我的代码: 1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNod

24. 两两交换链表中的节点

知乎ID: 码蹄疾 码蹄疾,毕业于哈尔滨工业大学. 小米广告第三代广告引擎的设计者.开发者: 负责小米应用商店.日历.开屏广告业务线研发:主导小米广告引擎多个模块重构: 关注推荐.搜索.广告领域相关知识; 题目 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3.说明: 你的算法只能使用常数的额外空间.你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 分析 两两合并节点,头结点

Leetcode篇:两两交换链表中的节点

@author: ZZQ @software: PyCharm @file: swapPairs.py @time: 2018/10/20 19:49 说明:给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 说明: 你的算法只能使用常数的额外空间. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 思路: 四个节点,分别记录当前需要进行交换的两个节点(first, seco

链表-LeetCode24两两交换链表中的节点

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 说明: 你的算法只能使用常数的额外空间. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 分析:类似于数组中的链表交换,题目中的head是实际的第一个带值的节点,而不是空头节点,由于不能出现空指针,所以,可以创建一个值为0的头结点. /** * Definition for singly-linked list. * st

力扣——两两交换链表中的节点

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class

leetcode 24. 两两交换链表中的节点(Swap Nodes in Pairs)

目录 题目描述: 示例: 解法: 题目描述: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示例: 输入:1->2->3->4 输出:2->1->4->3. 解法: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x