zoukankan      html  css  js  c++  java
  • 【Leetcode】【Medium】Swap Nodes in Pairs

    Given a linked list, swap every two adjacent nodes and return its head.

    For example,
    Given 1->2->3->4, you should return the list as 2->1->4->3.

    Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

    解题思路:

    传统的链表操作题,需要注意如果结点不是偶数,最后一个结点不需要交换,放在队尾。

    先条件:head不为空;head至少包含两个结点;

    后条件:返回指向新链表第一个结点的指针;原链表结点全部加入新链表中,并且偶数对结点两两互换;新旧链表的结点数一致。

    不变式:1、新建一个newhead指针,newhead->next永远指向新链表的头部;

        2、新建一个newlist指针,newlist永远指向新链表的最后一个结点;

        3、newlist->next始终为NULL;

        4、head指针永远指向还未被操作的旧链表第一个结点;

        5、新链表上的结点数加上旧链表剩余的结点数之和,应该和原链表结点数一致;

    当head为空时,循环结束,每次循环:

        1、将head中的结点按对取出~交换~插入newlist末端

        2、若head只剩一个结点不够一对,则直接插入newlist末端;

    解题步骤:

    1、新建preHead结点,新建newlist指针;

    2、按照不定式分析,开始循环,循环结束标志为head为空:

      (1)如果当前head只剩一个结点,则将其插入newlist后,并结束循环;

      (2)取出待操作的两个结点,head后移两位;

      (3)将这两个结点反转插入newlist中

    3、释放preHead,返回newlist;

    代码1:

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     ListNode* swapPairs(ListNode* head) {
    12         /*
    13         if (head == NULL || head->next == NULL) 
    14             return head;
    15         */
    16         ListNode* newhead = new ListNode(0);
    17         ListNode* newlist = newhead;
    18         ListNode* preNode = NULL;
    19 
    20         while (head != NULL) {
    21             if (head->next == NULL) {
    22                 newlist->next = head;
    23                 break;
    24             }
    25             preNode = head;
    26             head = head->next->next;
    27             preNode->next->next = preNode;
    28             newlist->next = preNode->next;
    29             newlist = preNode;
    30             newlist->next = NULL;
    31         }
    32         
    33         head = newhead->next;
    34         delete newhead;
    35         return head;
    36     }
    37 };

    代码2,使用二维指针:

    基本逻辑实现:

    1 ListNode **p = &head;
    2 while (*p && (*p)->next) {
    3     // n表示待交换的两个结点中,后一个结点
    4     ListNode* n = (*p)->next; 
    5     (*p)->next = n->next; 
    6     n->next = *p;
    7     p = &(*p)->next;
    8 }

    由于二维指针p一直在操作当前需要交换的结点,不断向后迭代,而head指针此时指向的是链表中第二个结点(前两个交换);

    因此上述代码唯一的问题是,没有指针指向头结点,无法返回...

    所以我们希望在第一轮交换时,将head结点重新指向交换后的第一个结点。观察到第一轮交换时,*p其实就代表head,操作*p的指向,就是操作head的指向。

    所以,最终代码为:

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     ListNode* swapPairs(ListNode *head) {
    12         ListNode **p = &head;
    13 
    14         while (*p && (*p)->next) {
    15             ListNode* n = (*p)->next;
    16             (*p)->next = n->next;
    17             n->next = *p;
    18             *p = n;
    19             p = &(*p)->next->next;
    20         }
    21 
    22         return head;
    23     }
    24 };
  • 相关阅读:
    .NET正则基础之——平衡组
    网站架构探索负载均衡的方式
    Sql2005 全文索引详解
    构架师之路(4) 里氏代换原则(Liskov Substitution Principle, LSP)
    Ubuntu 9.04 server安装nginx+php(fastcgi)
    构架师之路(2) 开闭原则(OpenClosed Principle,OCP)
    SQL Server中常用全局变量介绍
    构架师之路(3) 1 IoC理论的背景
    linux ubuntu 命令集合
    理解nginx 和 php(fastcgi)的关系
  • 原文地址:https://www.cnblogs.com/huxiao-tee/p/4513485.html
Copyright © 2011-2022 走看看