zoukankan      html  css  js  c++  java
  • 【LeetCode-链表】两两交换链表中的节点

    题目描述

    给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
    你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
    示例:

    给定 1->2->3->4, 你应该返回 2->1->4->3.
    

    题目链接: https://leetcode-cn.com/problems/swap-nodes-in-pairs/

    思路

    保存4个指针:当前节点curNode,当前节点的前一个节点preNode,当前节点的下一个节点nextNode(防止链表断掉),当前节点的下一个节点的下一个节点temp。创建一个新的链表头指向原来的head,然后将nextNode->next=curNode,curNode->next=temp,preNode->next=nextNode,这样交换了两个节点,然后将preNode更新为curNode,curNode更新为temp。重复这一过程,直至curNode为空。代码如下:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* swapPairs(ListNode* head) {
            if(head==nullptr || head->next==nullptr){
                return head;
            }
    
            ListNode* newHead = new ListNode(0);    //新的链表头
            newHead->next = head;
            ListNode* curNode = head;
            ListNode* preNode = newHead;
            ListNode* nextNode = nullptr;
            while(curNode!=nullptr){
                nextNode = curNode->next;
                if(nextNode==nullptr){  // 链表中有奇数个节点,最后一个不交换
                    break;
                }
                ListNode* temp = nextNode->next;
                nextNode->next = curNode;
                preNode->next = nextNode;
                curNode->next = temp;
                preNode = curNode;
                curNode = temp;
            }
            return newHead->next;
        }
    };
    

    也可以这样写:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* swapPairs(ListNode* head) {
            if(head==nullptr) return head;
            if(head->next==nullptr) return head;
    
            ListNode* dummy = new ListNode(0);
            dummy->next = head;
            ListNode* pre = dummy;
            ListNode* curNode = head;
            while(curNode!=nullptr && curNode->next!=nullptr){
                ListNode* nextNode = curNode->next;
                curNode->next = nextNode->next;
                nextNode->next = curNode;
                pre->next = nextNode;
                pre = curNode;
                curNode = curNode->next;
            }
            return dummy->next;
        }
    };
    

    基本是一样的,就把循环条件改了一下。

    • 时间复杂度: O(n)
    • 空间复杂度:O(1)

    总结

    这个题和翻转链表有点类似,交换两个节点实际上就是将nextNode->next指向curNode,这样的话最初nextNode指向的节点会丢失,链表会断掉。为了解决这个问题,需要一个变量保存nextNode最初指向的节点,在操作的过程中,可以画图模拟一下,找到模式。

  • 相关阅读:
    表达式计算
    atof和atoi
    十六进制与十进制之间的相互转换
    十六进制转八进制
    B. Blown Garland
    B. Arpa’s obvious problem and Mehrdad’s terrible solution
    ios::sync_with_stdio(false);
    1091 线段的重叠
    CODE[VS] 2614 安全区域
    CODE[VS] 2221 搬雕像 ——2011年台湾高级中学咨询学科能力竞赛
  • 原文地址:https://www.cnblogs.com/flix/p/12676401.html
Copyright © 2011-2022 走看看