每日算法之四十三:Rotate List (列表旋转k个元素)

本文探讨了如何对链表进行右旋转操作,通过k个位置的旋转,例如给定一个列表和k=3,返回旋转后的列表。关键在于处理k大于链表长度的情况,实际旋转位置为k%len(list)。文章介绍了使用三个辅助指针的简单旋转步骤,并建议查看更简洁高效的解决方案。
摘要由CSDN通过智能技术生成

Given a list, rotate the list to the right by k places, where k is non-negative.

For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.

这里的k可能是比链表长度要大的数字,因此实际旋转的位置就是k%len(list)。如果这个计算结果等于零或者等于len(list),列表是不用旋转的。

接下来如果是事例给出的正常情况,那么有三步就能完成旋转。

(1)第一个辅助指针从头开始后移k个位置。

(2)这时第二个辅助指针指向头指针,然后两个指针同时向后移动,知道第一个辅助指针指向尾节点。

(3)声明第三个辅助指针指向第二个辅助指针的后继结点作为将要返回的新头指针。把第二个指针的后继设为空指针,同时将第一个指针的后继指向原先的有指针。这儿样就能完成指针的旋转。

注:最后给出的另外另种方式更简洁高效,推荐先看一下。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *rotateRight(ListNode *head, int k)
{
	if(head == NULL || k <= 0)
		return head;
	
	ListNode *temp = head;
	int node_count = 0;
	while(temp != NULL)
	{
	    node_count++;
	    temp = temp->next;
	}
	
	if(k > node_count)
	   k = k%node_count;
	if(k == node_count || k == 0)
	   return head;
	
	ListNode *first = head;
	while(/*first != NULL && first->next != NULL &&*/ k > 0)
	{
		first = first->next;
		k--;
	}
	
	//if(k > 0)
	//	return head;
	ListNode *second = head;
	while(first->next != NULL)
	{
		first = first->next;
		second = second->next;
	}

	ListNode *newhead = second->next;
	first->next = head;
	second->next = NULL;
	return newhead;
}

};

这里有一个地方需要注意,在第一次完成的时候没有代码中的取余部分,因为没有考虑到循环移位的位数比链表长度长的情况,因此,在加上取余部分后,原代码中(即现在注释掉的部分)是不再需要的。因为这个时候的k一定比链表长度要小。因此这些判断是不在需要的。

下面是一些网上的答案,贴出来以供下次参考。

 ListNode *rotateRight(ListNode *head, int k) {  
        // Start typing your C/C++ solution below  
        // DO NOT write int main() function  
        if (head == NULL || head->next == NULL || k == 0) {  
            return head;  
        }  
          
        int length = 0;  
        ListNode *ptr = head, *tail = head;  
        while (ptr != NULL) {  
            length++;  
            tail = ptr;  
            ptr = ptr->next;   
        }  
        k %= length;  
          
        ptr = head;  
        for (int i = 0; i < length - k - 1; i++) {  
            ptr = ptr-> next;  
        }  
          
        tail->next = head;  
        head = ptr->next;  
        ptr->next = NULL;  
          
        return head;  
    }  
另一种更简洁的方式。

ListNode *rotateRight(ListNode *head, int k)
    {
        if(head==NULL)return NULL;
        ListNode *p=head;
        int n=0;
        while(p->next)
        {
            p=p->next;
            n++;
        }
        n++;
        k=k%n;
        p->next=head;
        ListNode *q=head;
        for(int i=0;i<n-k-1;i++)
        q=q->next;
        head=q->next;
        q->next=NULL;    
        return head;
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值