#leetcode刷题之路25- k个一组翻转链表

给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。

示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5

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

思路:先把是不是从头开始区分一下,然后每一次翻转之前,都要判断数量够不够k

#include <iostream>
using namespace std;
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

ListNode* createlist(int n)//生成链表
{
    if (n == 0) return nullptr;
    ListNode* head = (ListNode*)malloc(sizeof(ListNode));
    cin >> head->val;
    ListNode* pre = head;
    for (int i = 0; i < n - 1; i++)
    {
        ListNode* p = (ListNode*)malloc(sizeof(ListNode));
        cin >> p->val;
        pre->next = p;
        pre = pre->next;
    }
    pre->next = nullptr;
    return head;
}

ListNode* reverselist(ListNode* head, ListNode *p, int k)
{
    int tk = k;//暂时保存k的值
    if (head == p)//是头
    {
        ListNode* temp = head;//
        ListNode* endd = head;//
        ListNode* ttemp=nullptr;
        ListNode* pre = nullptr;//保存已反转的下一个
        ListNode* end = nullptr;//
        ListNode* t = head;//保存反转过的最后一个
        while (tk > 0)//说明从头节点开始有K个节点可供反转
        {
            if (temp != nullptr)
            {
                temp = temp->next;
                tk--;
            }
            else
                return head;
        }//while循环后temp指针指向链表的第K+1个节点
        //cout<<temp->val<<endl;
        //开始反转,让头指向空
        pre = head->next;
        head->next = nullptr;
        //cout<<temp->val<<endl;
        while (pre != temp)
        {
            //t = pre;
            end = pre->next;
            pre->next = head;
            head = pre;
            pre = end;
        }
        //cout << t->val << endl;
        endd->next = temp;//连接后面剩下的
        //带头的前k个处理完了,判断接下来的够不够k个
        tk = k;
        //temp = t;
        while (tk != 0)//是否可继续处理
        {
            if (temp != nullptr)
            {
                temp = temp->next;
                tk--;
            }
            else
                return head;
        }
        //cout << t->val <<t->next->val<< endl;
        //cout << head->val << head->next->val << endl;
        reverselist(head, t, k);//够的话就递归反转
    }
    else
    {
        ListNode* pre = p;//保存已经反转过的最后一个--------------------
        ListNode*cur = pre->next;//保存待反转的第一个
        ListNode* cur_next=cur->next ;//保存待反转的下一个
        ListNode* end = nullptr;//存放待反转的最后一个节点的下一个节点----------------------
        ListNode* thead=nullptr;//存放转后的头节点---------------
        ListNode* tcur = cur_next->next;//存放当前的cur_next的下一个节点,即下次要反转的那个------------------
        ListNode* temp = nullptr;//记录反转的链表尾
        ListNode* t = nullptr;//
        //-----------------------------先反转第一次

        cur_next->next = cur;
        cur->next = nullptr;
        temp = cur;
        thead = cur_next;
        tk = k-2;
        while (tk > 0)
        {
            cur = tcur;
            tcur = tcur->next;
            cur->next = thead;
            thead = cur;
            tk--;
        }
        pre->next = thead;
        temp->next = tcur;
        t = temp->next;
        //带头的前k个处理完了,判断接下来的够不够k个
        tk = k;
        //temp = t;
        while (tk != 0)//是否可继续处理
        {
            if (t != nullptr)
            {
                t = t->next;
                tk--;
            }
            else
                return head;
        }
        reverselist(head, temp, k);//够的话就递归反转
    }
    return head;
}

ListNode* reverseKGroup(ListNode* head, int k) {
    if (head == nullptr || k == 0 || k == 1) return head;
    ListNode *temp = head;
    head = reverselist(head, head, k);
    return  head;
}

int main() {
    ListNode* head = createlist(4);
    ListNode*ans = reverseKGroup(head, 2);
    while (ans != nullptr)
    {
        cout << ans->val << endl;
        ans = ans->next;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/biat/p/10560833.html

时间: 2024-08-26 18:14:27

#leetcode刷题之路25- k个一组翻转链表的相关文章

[leetcode] 25. k个一组翻转链表

25. k个一组翻转链表 仍然是链表处理问题,略微复杂一点,边界条件得想清楚,画画图就会比较明确了. reverse函数表示从 front.next节点开始,一共k个节点做反转. 即: 1>2>3>4>5 ,k = 2.当front为1时, 执行reverse后: 1>3>2>4>5 同上个题一样,申请一个空的(无用的)头指针指向第一个节点,会方便许多. public ListNode reverseKGroup(ListNode head, int k)

[LeetCode] 25. K 个一组翻转链表 ☆☆☆☆☆(链表)

https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/javadi-gui-fang-fa-100-by-chadriy-imdgvs6udp/ https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/tu-jie-kge-yi-zu-fan-zhuan-lian-biao-by-user7208t/ 描述 给你一个链表,每 k 个节点一组

[LeetCode] Reverse Nodes in k-Group 每k个一组翻转链表

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. You may not alter the values in the nodes, only nod

25. k个一组翻转链表-LeetCode

心得:反转链表加强版,加头节点简化操作,然后写一个方法调用 反转链表,注意next的操作,边界条件!! 代码: 1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; } 7 * } 8 */ 9 class Solution { 10 public ListNode reverse

25. K 个一组翻转链表

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度. 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序. 示例 : 给定这个链表:1->2->3->4->5 当 k = 2 时,应当返回: 2->1->4->3->5 当 k = 3 时,应当返回: 3->2->1->4->5 来源:力扣(LeetCode)链接:https://leetcode-cn.com

25. k个一组翻转链表

题目描述: 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序. 示例 : 给定这个链表:1->2->3->4->5 当 k = 2 时,应当返回: 2->1->4->3->5 当 k = 3 时,应当返回: 3->2->1->4->5 说明 : 你的算法只能使用常数的额外空间. 你不能只是单纯的改变节点内部的值,

leetcode 刷题之路 93 Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 将k个有序链表合并成一个有序链表. 思路,之前做过两个有序链表的合并操作,对于k个链表,我们最先想到的就是能不能转化为我们熟悉的两个链表的合并,可以我们先将k个链表分为两部分,先对这两部分完成链表的有序合并操作,再对合并得到的两个链表进行合并,这是一个递归性质的描述,采用递归很容易实现这个程序,和数组

leetcode 刷题之路 77 Permutations II

Given a collection of numbers that might contain duplicates, return all possible unique permutations. For example, [1,1,2] have the following unique permutations: [1,1,2], [1,2,1], and [2,1,1]. Permutations 的升级版,依旧是全排列问题,但是序列中可能会出现重复数字. 思路:采用字典序的非递归方

【leetcode刷题笔记】Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 题解:最开始用了最naive的方法,每次在k个链表头中找出最小的元素,插入到新链表中.结果果断TLE了. 分析一下,如果这样做,每取出一个节点,要遍历k个链表一次,假设k个链表一共有n个节点,那么就需要O(nk)的时间复杂度. 参考网上的代码,找到了用最小堆的方法.维护一个大小为k的最小堆,存放当前k

leetcode 刷题之路 63 Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its zig