【LeetCode刷题笔记-85 61:旋转链表(两种做法,附带完整测试)】

题目:
在这里插入图片描述
今天这题有两种做法.

题解的闭合成环是一种做法,但是这种做法之前没有接触过的话会有点难想。

借助以前的知识好做的一种做法是设立虚头节点然后对尾元素做摘链插入就可以了。

先讲讲第二种吧,因为设立虚节点基本是链表题必想的方法。

很简单,设置一个suphead放在最前面,然后设置两个指针,ptr遍历指向尾部节点pre指向尾部前面的一个节点。这样就可以完成摘链。并且也可以用头插法将尾节点插入头节点。

只不过要注意返回的时候返回的是suphead->next,并且需要清理suphead的内存空间

这里要注意,需要对输入的k进行处理,不然会超过时间限制。

闭合成环就像题解说的那样,闭合然后循环,同样需要对k进行处理,不然也会超过时间限制。

两种方法的C++代码:

#include<iostream>


using namespace std;

/**
 * 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) {}
 * };
 */
 

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){}
};

ListNode* createList(){
	ListNode* head = new ListNode(0);
	ListNode* ptr = head;
	int arr[] = {1,2,3,4,5};
	int n = sizeof(arr)/sizeof(int);
	for(int i=0;i<n;i++){
		ListNode* p = new ListNode(arr[i]);
		ptr->next = p;
		ptr = ptr->next;
	}
	
	return head;
}

void display(ListNode* head){
	ListNode* p = head;
	while(p!=nullptr){
		cout<<p->val<<" ";
		p = p->next;
	}
	cout<<endl;
}

class Solution {//虚节点法 
public:
	ListNode* swap(ListNode* suphead){//虚头节点一起传入 
		ListNode* ptr = suphead->next;
		ListNode* pre = suphead;
		if(ptr==nullptr){
			return suphead;//虚头节点一起回传 
		}
		while(ptr->next!=nullptr){
			ptr = ptr->next;
			pre = pre->next;
		}
		//循环结束之后ptr找到的是尾节点,pre找到的是尾节点的上一
		
		ptr->next = suphead->next;//插入到头的位置
		pre->next = nullptr;//尾节点的下一个为空
		suphead->next = ptr;//头指向尾节点 
		
		return suphead;
	}
	
    ListNode* rotateRight(ListNode* head, int k) {
    	if(head==nullptr){
    		return head;
		}
		if(head->next==nullptr){
			return head;
		}
		ListNode* suphead = new ListNode(0);
		suphead->next = head;
		
		int n = 1;
		ListNode* ptr = head;
		while(ptr->next!=nullptr){
			ptr = ptr->next;
			n++;
		}
		
		int last = k%n;
		if(last==n){
			delete suphead;
			return head;
		}
		
		while(last--){
			suphead = swap(suphead);
		}
		
		ListNode* p = suphead->next;
		delete suphead;
		return p;
    }
};

//class Solution {//循环法 
//public:
//    ListNode* rotateRight(ListNode* head, int k) {
//        if (k == 0 || head == nullptr || head->next == nullptr) {
//            return head;
//        }
//        int n = 1;//统计链表长度
//		ListNode* ptr = head;
//		while(ptr->next!=nullptr){
//			ptr = ptr->next;
//			n++;
//		}
//		
//		int last = n-k%n;
//		if(last ==n){
//			return head;
//		} 
//		
//		ptr->next = head;
//		for(int i=0;i<last;i++){
//			ptr = ptr->next;
//		}
//		
//		ListNode* ans = ptr->next;
//		ptr->next = nullptr;
//		return ans;
//		
//    }
//};

int main(){
	ListNode* head = createList();
	display(head);
	Solution solution;
	head = solution.rotateRight(head->next,2);
	display(head);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值