【LeetCode 0-Start】[数组]数组的旋转

本文介绍两道中等难度的LeetCode题目:“189.旋转数组”与“396.旋转函数”。针对每道题,分别提供两种Java实现方案:一种为直观但效率较低的方法,另一种则是通过巧妙的数学关系或反转操作来提高效率。
摘要由CSDN通过智能技术生成

【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;//返回最大值
    }	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值