【LeetCode 0-Start】[数组]数组的旋转
前言
数组的旋转
题目序号: 189、396
一、[中等]189. 旋转数组
题目来源
算法思想:数组;
java代码–暴力
思路: 每一次数组向后移动一个位置,移动k次
class Solution {
public void rotate(int[] nums, int k) {
int n = k % nums.length;//避免移动一圈
for (int i = 0; i < n; i++) {//移动k次
int tmp = nums[nums.length-1];
for (int j = nums.length - 1; j > 0; j--) {//每次移动一个位置,将元素向后移动
nums[j] = nums[j-1];
}
nums[0] = tmp;
}
}
}
java代码–反转
思路: 使用反转
分析来源.
class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length;//避免移动一圈
invert(nums, 0, nums.length-1);//反转所有数字
invert(nums, 0, k-1);//反转前k个数字
invert(nums, k, nums.length-1);//反转后n-k个数字
}
//反转函数
private void invert(int[] nums, int i, int j) {
//i指向需要翻转数组的头, j指向需要翻转数组的尾,
while (i < j) {//当i在j前面,交换两个指向的值,i++,j--;
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
i++;
j--;
}
}
}
二、[中等]396. 旋转函数
题目来源
算法思想:数组;
java代码–暴力
直观,暴力解法,不优
class Solution {
public int maxRotateFunction(int[] A) {
int n = A.length;
if (n < 2) {//如果长度小于2,必定是0,直接返回
return 0;
}
int max = Integer.MIN_VALUE;//设定最小值
for (int i = 0; i < n; i++) {//遍历n次,每次计算F(i)
int sum = 0;//F(i)=0,初始化
for (int j = 0; j < A.length; j++) {//计算F(i)
sum += j * A[j];
}
if (sum > max) {//记录最大值
max = sum;
}
invertOne(A);//旋转一次,便于计算F(i+1)
}
return max;//返回最大值
}
//将数组元素向后移动一位,最后一位放到第一位
private void invertOne(int[] nums) {
int tmp = nums[nums.length-1];
for (int j = nums.length - 1; j > 0; j--) {//每次移动一个位置,将元素向后移动
nums[j] = nums[j-1];
}
nums[0] = tmp;
}
}
java代码–利用F(k)与F(k+1)的关系
class Solution {
public int maxRotateFunction(int[] A) {
if(A.length < 2) {//如果长度小于2,必定是0,直接返回
return 0;
}
int sum = 0;//统计A数组元素总和
int F0 = 0;
for(int i = 0; i < A.length; i++) {//统计F(0)
sum += A[i];
F0 += i * A[i];
}
int max = F0;//最大值
for(int i = 1; i < A.length; i++) {//从F(1)开始计算
int F1 = F0 + sum - A.length * A[A.length-i];//递推公式
if(F1 > max)//记录最大值
max = F1;
F0 = F1;//迭代
}
return max;//返回最大值
}
}