《程序员代码面试指南》it名企算法与数据结构题目最优解(第二版)刷题笔记11

由于之前看了牛客网的数据结构和算法的课程知道了左神,现在找到了这本书当作入门书做做吧,虽然书的题解都是java实现的,但好在用c++实现难度不大

第二章 链表问题

题目一:将单链表的每k个节点之间逆序
给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点
方法一:利用栈结构,时间复杂度O(N),空间复杂度O(k)

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

class Solution {
public:

	ListNode* reverseKGroup(ListNode* head, int k) {
		if (!head||k<2)
		{
			return head;
		}
		//如果没有下面的判断,输入 [1] 2 解答将会错误
		int num=0;
		ListNode* count=head;
		while(count){
			num++;
			count=count->next;
		}
		if(k>num){return head;}
		stack stack1;
		//这里是变量
		ListNode* cur=head,*newhead=nullptr,*pre=nullptr,*next=nullptr;//没有next,根本无法遍历
		while (cur)
		{
			next=cur->next;//为了遍历
			stack1.push(cur);
			if (stack1.size()==k)
			{
				pre=reverse(stack1,pre,next);
				newhead=newhead==nullptr?cur:newhead;//第一组节点的特殊处理,得到要返回的头结点
			}
			cur=next;//之前是cur=cur->next,错了,因为cur->next已经是被翻转过来的一个节点了,不是我们想要的原先cur->next了
		}
		return newhead;
	}
	ListNode* reverse(stack &stack1,ListNode* left,ListNode* right){
		if (left)//第一组节点的特殊处理,之前小括号里是!left,报错
		{
			left->next=stack1.top();
		}
		ListNode* cur=stack1.top();//方便接下来while循环里的操作
		while (!stack1.empty())
		{
			cur->next=stack1.top();
			stack1.pop();
			cur=cur->next;
		}
		cur->next=right;//没加这个出现右侧不够k值时没有被连上的情况
		return cur;
	}
};

方法二:不需要栈结构,在原链表中直接调整
1.注意第一组节点的特殊处理
2.留意每个组在逆序重连之后,需要让该组的第一个节点(原来是最后一个节点)被之前组的最后一个节点连接上,将该组的最后一个节点(原来是第一个节点)连接下一个节点

class Solution{
public:
	ListNode* reverseKGroup(ListNode* head,int k){
		if (!head||k<2)
		{
			return head;
		}
		//如果没有下面的判断,输入 [1] 2 解答将会错误
		int num=0;
		ListNode* count=head;
		while(count){
			num++;
			count=count->next;
		}
		if(k>num){return head;}
		ListNode* pre=nullptr,*cur=head,*next=nullptr,*start=nullptr,*newhead=nullptr;
		int count1=1;
		while (cur!=nullptr)
		{
			next=cur->next;
			if (count1==k)
			{
				start=pre==nullptr?head:pre->next;//没有给start赋值
				head=pre==nullptr?cur:head;
				reverse(pre,start,cur,next);//start不能用pre->next代替,因为第一组节点特殊处理
				pre=start;
				count1=0;
			}
			count1++;
			cur=next;
		}
		return head;
	}
	void reverse(ListNode* left,ListNode* start,ListNode* end,ListNode* right){

		ListNode* pre=start;
		ListNode* cur=start->next;
		ListNode* next=nullptr;
		while (cur!=right)
		{
			next=cur->next;
			cur->next=pre;
			pre=cur;
			cur=next;
		}
		if (left!=nullptr)
		{
			left->next=end;
		}
		start->next=right;//右边没连起来
	}
};

你可能感兴趣的:(《程序员代码面试指南》it名企算法与数据结构题目最优解(第二版)刷题笔记11)