Easy | LeetCode 189 | 旋转数组

本文详细介绍了在LeetCode上解决数组旋转问题的三种不同算法,包括两次反转法、优化后的元素移动法以及循环替换法。每种方法都附有详细的步骤解析和C++代码实现,旨在帮助读者理解并掌握如何在不使用额外空间的情况下,高效地完成数组元素的旋转操作。

链接:https://leetcode-cn.com/problems/rotate-array
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]

说明:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
要求使用空间复杂度为 O(1) 的 原地 算法。

思路一:
两次反转, 先反转整个,然后依次反转[0, k), [k, n)
时间复杂度:O(n) 。
缺点: n个元素被反转了总共 2次。
空间复杂度:O(1) 。 没有使用额外的空间。

void rotate(vector<int>& nums, int k) {
    if (nums.size() < 2)
        return;
    if (k >= nums.size())
        k = k % nums.size();
    if (k==0)
        return;
    std::reverse(nums.begin(), nums.end());
    std::reverse(nums.begin(), nums.begin()+k);
    std::reverse(nums.begin()+k, nums.end());
}

思路二:

思路一种每个元素经历了两次反转。为优化这个问题, 可以先保存后K个元素, 然后将前N-k个元素向后移动K位, 再把保存的K个元素移到开头

时间复杂度: O(n)
空间复杂度: O(k)

void rotate(vector<int>& nums, int k) {
	int len = nums.size();
	int i = k % len;
	// 保存后K个元素
	for (int j = i; j > 0; j--) {
		nums.push_back(nums[len-j]);
	}
	//将前N-K个元素向后移动K位
	for (int j = len - 1; j >= i; j--) {
		nums[j] =nums[j-i];
	}
    //将后K个元素放到开头
	for (int j = 0; j < i; j++) {
		nums[j] = nums[len+j];
	}
    //删除刚刚保存的K个元素
	nums.erase(nums.begin()+len, nums.end());
}

思路三:

如果我们直接把每一个数字放到它最后的位置,但这样的后果是遗失原来的元素。因此,我们需要把被替换的数字保存在变量 temptemp 里面。然后,我们将被替换数字(temptemp)放到它正确的位置,并继续这个过程n次。

当然可能经过若干次过后, 回到起点, 所以如果回到起点就从下一个位置开始。

时间复杂度: O(n)
空间复杂度: O(1)

void rotate(vector<int>& nums, int k) {
	int count = 0;
	int current, next;
	int preValue, postValue;
	int len = nums.size();
	k %= len;
	for (int start = 0; count < len; start++) {
		current = start;
		preValue = nums[start];
		do {
			next = (current + k) % len;
			postValue = nums[next];
			nums[next] = preValue;
			count++;
			current = next;
			preValue = postValue;
		} while (current != start);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值