【PAT_C8】JAVA

Question:

一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A​0​​A​1​​⋯A​N−1​​)变换为(A​N−M​​⋯A​N−1​​A​0​​A​1​​⋯A​N−M−1​​)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:

每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。

输出格式:

在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:

6 2
1 2 3 4 5 6

输出样例:

5 6 1 2 3 4

解决思路:数组循环移动是一种比较常见的问题,本题需要不借助另外的数组,并且要求移动次数较少,于是想起了考研数据结构中一种常见的解题思路:先将整体数组(下标0->数组末尾)reverse,然后将前半部分(从下标0->移动步数对应的下标)reverse,然后将后半部分(移动步数对应下标->数组末尾)

具体步骤:

具体如下,假设数组长度为6,循环右移2位,对应的步骤为

1.初始化数组:

1 2 3 4 5 6

2.整体reverse:

[ 6 5 4 3 2 1 ]

3.前半部分reverse:

[5 6] 4 3 2 1

4.后半部分reverse:

5 6 [ 1 2 3 4 ]

5.得到结果:

5 6 1 2 3 4

package PATC8;
import java.util.Scanner;
public class Main {
	//翻转数组,从下标start->end
	public static void reverse(Integer arr[],int start,int end)
	{
		int front=start,rear=end;
		//System.out.println("(front:"+front+" rear:"+rear+")/2:"+(front+rear)/2);
		for(int i=front;i<=(front+rear)/2;i++,end--)
		{
			//System.out.println("swap:["+arr[i]+"] and ["+arr[end]+"]");
			int tmp=arr[i];
			arr[i]=arr[end];
			arr[end]=tmp;
		}
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		//得到第一行数据
		String num=sc.nextLine();
		String[] split_num = num.split(" ");
		//得到数组位数以及移动步数,这是个坑,容易忽略
		int nums=Integer.parseInt(split_num[0]);
		int steps=Integer.parseInt(split_num[1]);
		//循环移动的步数可能会大于数组长度,因此取余就可以了
		steps=steps%nums;
		//得到第二行输入
		Integer[] arr=new Integer[nums];
		String arr_value=sc.nextLine();
		String[] split_arr_value = arr_value.split(" ");
		//初始化数组
		for(int i=0;i<split_arr_value.length;i++)
		{
			arr[i]=Integer.parseInt(split_arr_value[i]);
		}
		//如果移动的步数为0,do nothing
		if(steps==0)
		{
			//do nothing
		}
		//否则,不移动
		else
		{
			//for(Integer i:arr)System.out.print(i+" ");System.out.println();
			reverse(arr,0,nums-1);
			//for(Integer i:arr)System.out.print(i+" ");System.out.println();
			reverse(arr,0,steps-1);
			//for(Integer i:arr)System.out.print(i+" ");System.out.println();
			reverse(arr,steps,nums-1);
			//for(Integer i:arr)System.out.print(i+" ");
		}
		//输出
		for(int i=0;i<nums-1;i++)
		{
			System.out.print(arr[i]+" ");
		}
		System.out.print(arr[nums-1]);
	}
}

补充:这个问题有个容易忽略的地方,就是因为是循环移动,移动的步数可能大于数组的长度,因此在操作之前先让其对长度取模,然后再翻转。此外,在翻转时还应该要考虑移动步数为0的情况,此时做一个简单的判断,让程序什么都不做即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值