【leetcode】25. Reverse Nodes in k-Group

博客围绕LeetCode上“Reverse Nodes in k-Group”这一难题展开,将每个k长度内视为完整链表逆序问题。给出解题思路,先写链表逆序函数,再思考外部循环逻辑,还提及两种情况及几个易忽略的边界情况,最后给出代码。

25. Reverse Nodes in k-Group

Hard

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of kthen left-out nodes in the end should remain as it is.

Example:

Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5

Note:

  • Only constant extra memory is allowed.
  • You may not alter the values in the list's nodes, only nodes itself may be changed.

链接:https://leetcode.com/problems/reverse-nodes-in-k-group/

 

这道题虽然是hard,但把每个k长度内看成一个完整的链表逆序问题就很简单。

思路是:

1)先写出链表逆序的函数:输入为链表头节点指针,链表尾节点的下一节点的指针;输出为逆序后链表的头节点指针。

2)思考外部循环的逻辑:指针last记录已完成链表部分的尾节点指针,指针l和r表示下一段逆序的k长度链表的头尾(是逆序函数的输入),int i用来记录下一段的长度是否达到k。

两种情况:

1⃣️下一段长度为k,对该段调用逆序,新链表接到last之后,更新l、r、last,循环继续。

2⃣️下一段长度小于k,直接接到last之后,退出循环。

注意:其中有几个容易忽略的边界情况:

1⃣️链表长度小于k:判断标准是l==head,此时直接返回head。

 

注:其实指针l不是必须的,可以用last->next代替。做题时为了思路更清晰而设计,回顾时发现可以删除。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if (head == NULL || k <= 1) return head;
        ListNode  *last = head, *l = head, *r = head; // last: end of reversed list; l/r: count k;
        while(r != NULL){
            int i = 0;
            while(r != NULL && i < k){
                r = r -> next;
                ++i;
            }
            if(i == k){
                ListNode* tmp = reverse(l, r);
                if(last == head){
                    head = tmp;
                }
                else{
                    last -> next = tmp;
                }
                last = l;
                l = r;
            }else{
                if(last != head) last -> next = l;
                break;
            }
        }
        return head;
    }
    ListNode* reverse(ListNode* head, ListNode* end){
        if(head == NULL) return NULL;
        ListNode* last = head, *cur = last -> next;
        while(cur != end){  // end point to the next addr which not reverse
            ListNode* next = cur -> next;
            cur -> next = last;
            last = cur;
            cur = next;
        }
        head -> next = NULL;
        return last;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值