leetcode 24 两两交换链表中的节点(c++和python)

目录

题目描述:

解题思路:

 C++代码:

c++代码 (思路2)

python代码:


题目描述:

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

示例:

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

说明:

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

解题思路:

 定三个指针:pre指向前面节点, cur指向当前节点, post指向后面节点。指向如下:

先将pre->next指向后面的节点post , 再交换cur和post位置:cur->next = post->next; post->next = cur;

 交换后变成:

移动到下一组,即3,4的一组,pre移动到 1: pre = pre->next->next; 这样pre指向1,判断后面是否有两个节点,即pre-next和pre->next->next。

 C++代码:

/**
 * 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) {
        
        ListNode * dummy = new ListNode(0);  // 生成哑结点,并指向真正的头结点head
        dummy->next = head;
        ListNode* pre = dummy;
        while(pre->next && pre->next->next){
            ListNode* cur = pre->next;
            ListNode* post = pre->next->next; // cur和post组成当前需要交换的一组
            
            pre->next = post;  // 指向后面的节点,使其成为前面的节点
            
            cur->next = post->next; // 交换cur和post两个节点的位置
            post->next = cur;
            
            pre = pre->next->next; // 下一组
        }
        
        return dummy->next;
    }
};

c++代码 (思路2)

四个指针,slow,p,q,fast,其中slow和fast指向要交换两个节点p和q的前一个节点和后一个节点,

交换p和q,只要q不为空,则一直交换,否则停止。

执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户

内存消耗:7.3 MB, 在所有 C++ 提交中击败了66.28%的用户

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        // 特殊情况,空或者只有一个节点
        if (head == nullptr || head->next == nullptr) return head;

        // 4个指针slow,p,q,fast. slow指向要交换两个节点p和q的前一个节点和后一个节点
        ListNode* p_head = new ListNode(0);
        p_head->next = head;
        
        ListNode* slow = p_head;
        ListNode* p = slow->next;
        ListNode* q = p->next;  // 前面排除了一个节点的情况,所以q肯定不为空
        ListNode* fast = q->next;
        while (q)  // q不空,p肯定不空,只要这两个不空,则需要交换
        {   
            // 交换
            p->next = q->next;
            q->next = p;
            slow->next = q;  // 由于更换了pq,所以slow下一个节点换成了q

            // 更新slow,p,q,fast
            slow = p;  // 前面更换了pq
            if (slow->next == nullptr || slow->next->next == nullptr) break;  // 只要p或者q为空,则停止交换
            else
            {
                p = slow->next;  // p可能为空
                q = p->next;
                fast = q->next;
            }
        }
        return p_head->next;
    }
};

python代码:

执行用时:16 ms, 在所有 Python 提交中击败了72.97%的用户

内存消耗:13.2 MB, 在所有 Python 提交中击败了35.34%的用户

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        # 特殊情况
        if head is None or head.next is None: return head

        # slow,p,q,fast
        p_head = ListNode(0)
        p_head.next = head

        slow = p_head
        p = slow.next
        q = p.next
        fast = q.next
        while q is not None:  # 只要q不空,则p和q都不空
            # 交换
            p.next = q.next
            q.next = p
            slow.next = q 

            # 更新slow,p,q,fast
            slow = p
            if slow.next is None or slow.next.next is None: break  # p或者q为空,则不更新了,直接跳出循环
            else:
                p = slow.next
                q = p.next
                fast = q.next
        return p_head.next

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值