leetcode 25:Reverse Nodes in k-Group(15-10-11)

题目:

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 nodes itself may be changed.

Only constant memory is allowed.

For 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

思路:

在做这道题之前我们先来研究下单链表的反转。

步骤:

  1. 定义当前结点 current,初始值为首元结点,current = L->next;
  2. 定义当前结点的后继结点 pnext, pnext = current->next; 
  3. 只要 pnext 存在(不为空),就执行以下循环:
    • 定义新节点 prev,它是 pnext的后继结点,prev = pnext->next(保存pnext的后继);
    • 把pnext的后继指向current, pnext->next = current;
    • 此时,pnext 实际上已经到了 current 前一位成为新的current,所以这个时候 current 结点实际上成为新的 pnext,current = pnext;
    • 此时,新的 current 就是 pnext,current = pnext(循环往后);
    • 而新的 pnext 就是 prev,pnext = prev;
  4. 最后将头结点与 current 重新连上即可,L->next = current;
实现代码:

Node * ReverseList(Node *head)  
{  
    Node *p1,*p2,*p3;  
    if(head==NULL||*head==NULL)  
    return head;  
    p1=head;  
    p2=p1->next;  
    while(p2)             //注意条件  
    {  
        p3=p2->next;       //要改变p2->next的指针,所以必须先保留p2->next           
        p2->next=p1;  
        p1=p2;            //循环往后  
        p2=p3;  
    }  
    head->next=NULL;   //原先的head已经变成tail,别忘了置空,只有到这步才能置空  
    *head=p1;  
    return head;  
} 


好了,下面可以开始求解这道题了。

先判断链表的长度是否大于k,如果不是,则返回head,否则,可以递归分解为若干个长度为k的链表,反转后再接起来,用递归进行。

反转方法为上面算法。


#include<iostream>
#include <string>
#include <stack>
#include <vector>
using namespace std;

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

class Solution1 {
public:
	ListNode* swapPairs(ListNode* head) {
		if (head == NULL) return NULL;
		if (head->next == NULL) return head;
		ListNode *p = head->next;
		head->next = swapPairs(p->next);
		p->next = head;
		return p;
	}
};

class Solution {
public:
	ListNode* reverseKGroup(ListNode* head, int k) {
		ListNode *p = head;
		if (p == NULL) return NULL;
		int i = 0;
		for (; i < k &&p != NULL; i++) p = p->next;
		if (i < k ) return head;

		ListNode *p1, *p2, *p3;
		p1 = head;
		p2 = p1->next;
		for (i = 0; i < k - 1; i++)
		{
			p3 = p2->next;             
			p2->next = p1;
			p1 = p2;            
			p2 = p3;
		}
		head->next=reverseKGroup(p2, k);
		head = p1;
		return head;
	}
};


int main()
{
	Solution s;
	ListNode *a1 = new ListNode(1);
	ListNode *a2 = new ListNode(2);
	ListNode *a3 = new ListNode(3);
	ListNode *a4 = new ListNode(4);
	ListNode *a5 = new ListNode(5);
	a1->next = a2;
	a2->next = a3;
	a3->next = a4;
	a4->next = a5;
	ListNode *result = s.reverseKGroup(a1,3);
	while (result != NULL)
	{
		cout << result->val << " ";
		result = result->next;
	}
	cout << endl;
	return 0;
}



时间复杂度分析:

长度为k的链表反转的时间复杂度为:O(k)

判断长度是否大于k的时间复杂度为:O(k)

递归次数为(n/k+1)

所以总的时间复杂度为:O(2K*(n/k+1))=O(n)
leetcode 25:Reverse Nodes in k-Group(15-10-11)_第1张图片













你可能感兴趣的:(leetcode 25:Reverse Nodes in k-Group(15-10-11))