C++程序 将给定数组旋转以使其成为非递减数组
在本文中,我们将学习如何将给定数组旋转,以使其成为非递减数组。首先让我们看看什么是非递减数组。
在非递减序列中,当且仅当每个元素不小于前一个元素时,它被认为是递增的。我们可以将非递减序列定义为整数数组,其中相邻的元素不严格递减。
例如,以下数组是非递减的,因为每个元素不小于前一个元素:
[1, 3, 3, 5, 8, 8]
而以下数组不是非递减的,因为前两个元素大于后两个元素:
[2, 4, 1, 6, 8]
为了将给定数组旋转成非递减数组,我们需要对其进行一次旋转。这意味着我们需要将数组中的一些元素移动到另一个位置。这可以通过在数组中旋转元素来完成。旋转数组意味着将其所有元素向右移动k个位置,其中k是非负整数。例如,旋转数组[1,2,3,4,5,6,7]三次得到[5,6,7,1,2,3,4]。
现在,让我们来看看如何将数组旋转成非递减数组。这可以通过以下步骤来完成:
- 找到数组中的旋转点,即数组中第一个元素大于下一个元素的位置。
-
将数组分为两个子数组,其中第一个子数组包含原数组中旋转点前的元素,第二个子数组包含原数组中旋转点后的元素。
-
将第一个子数组中的元素移到第二个子数组中。
-
将第二个子数组排序。
-
将两个子数组合并成一个数组。
下面是一个用C++编写的示例程序,它将旋转数组转换为非递减数组。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k %= n;
reverse(nums.begin(), nums.end());
reverse(nums.begin(), nums.begin() + k);
reverse(nums.begin() + k, nums.end());
}
void makeNonDecreasing(vector<int>& nums) {
int n = nums.size();
int pivot = n - 1;
for (int i = n - 1; i >= 1; i--) {
if (nums[i - 1] > nums[i]) {
pivot = i - 1;
break;
}
}
reverse(nums.begin(), nums.begin() + pivot + 1);
reverse(nums.begin() + pivot + 1, nums.end());
rotate(nums, n - pivot - 1);
}
int main() {
vector<int> nums = { 4, 5, 6, 7, 1, 2, 3 };
makeNonDecreasing(nums);
for (int num : nums) {
cout << num << " ";
}
cout << endl;
// Output: 1 2 3 4 5 6 7
return 0;
}
在这个程序中,我们首先定义了一个rotate
函数,它将数组向右旋转k个位置。然后,我们定义了makeNonDecreasing
函数,它实现了上面提到的步骤1到5。最后,我们使用一个示例数组来演示如何使用该函数来将数组旋转成非递减数组。
现在,让我们对这个程序进行一些解释。在rotate
函数中,我们首先计算出旋转量k的模数。然后,我们使用reverse
函数反转整个数组。接下来,我们使用reverse
函数来反转前k个元素和后n-k个元素,这样数组就被旋转了k个位置。
在makeNonDecreasing
函数中,我们首先定义了一个变量pivot
,它表示数组中的旋转点。我们从数组的末尾开始遍历,一旦找到前一个元素大于当前元素,就将pivot设置为当前元素的下标,并跳出循环。这样,我们就找到了数组中的旋转点。
接下来,我们使用两次reverse
函数来分别反转旋转点前和旋转点后的子数组。注意,我们是将pivot作为下标来传递给reverse
函数的,因此我们需要将其加1使其成为最后一个元素的下标。
最后,我们使用rotate
函数将数组向右旋转n-pivot-1个位置,这样既可以将原来旋转点前的元素移到数组末尾,又可以保证最终数组是非递减的。
结论
在本文中,我们学习了如何将给定数组旋转成非递减数组的C++程序。我们按照特定的步骤分割数组,并使用reverse
和rotate
函数来对数组进行操作。这个程序非常简单,但却很有效,可以在O(n)的时间复杂度内将任何旋转数组转换为非递减数组。