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

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

每日算法之四十三:Rotate List (列表旋转k个元素),布布扣,bubuko.com

时间: 2024-08-07 10:03:25

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

每日算法之四十二:Permutation Sequence (顺序排列第k个序列)

The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3): "123" "132" "213" "231" "312" "

每日算法之四十一:Spiral Matrix II (螺旋矩阵)

Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For example, Given n = 3, You should return the following matrix: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 针对这个问题采用最直观的方式即可,即螺旋插入,这里有两个地方需要注意,一个是插入边界的界定,

每日算法之四十:Insert Interval

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times. Example 1: Given intervals [1,3],[6,9], insert and merge 

每日算法之三十三:Trapping Rain Water

这是一个很有意思的问题,求解最大容积问题,值得动脑筋想一想. 原题如下: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. The ab

每日算法37:Rotate Image (图像旋转)

You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Follow up: Could you do this in-place? 原地图像顺时针旋转90度.由于要求空间复杂度是常数,因此应该迭代旋转操作. class Solution { public: void rotate(vector<vector<int> > &mat

(每日算法)LeetCode --- Reverse Linked List II(旋转链表的指定部分)

Reverse Linked List II(旋转链表的指定部分) Leetcode Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->5->NULL. Note: Given m, n sati

每日算法之四十四:Unique Path(矩阵中不重复路径的数目)

Unique Paths: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked

每日算法之四十八:Plus One (数组表示的十进制加一进位)以及求Sqrt(x)

给定数组表示的十进制数,加一操作.结果依然用十进制的数组表示.这里主要注意最高位(digit[0])依然有进位,即溢出的情况. Given a non-negative number represented as an array of digits, plus one to the number. The digits are stored such that the most significant digit is at the head of the list. <span style=

每日算法之四十七:Valid Number (验证是否为数字)

要想正确的写出这个函数不是件容易的事情,因为要考虑的事情很多: 1)字符串的前后都可能会有空格,但是中间不允许有空格. 2)可能有小数,1.235,或者.3522这种形式 3)可能有指数形式,2e10   2e-1等形式 Validate if a given string is numeric. Some examples: "0" => true " 0.1 " => true "abc" => false "1