java面试题算法(一)--交换数组和索引的值

题目:一副从1到n的牌,每次从牌堆顶取一张放桌子上,再取一张放牌堆底,直到手上没牌,最后桌子上的牌是从1到n有序,设计程序,输入n,输出牌堆的顺序数组。(题目来源于一篇知乎上的文章)

思路:

        在原牌堆a[n]以1到n的方式进行标记(即 a[0]=1,a[1]=2...),通过上述操作,产生新牌堆b[n]。若b[k]中的数值t+1,为原牌堆a[t]对应的位置,说明新牌堆第k+1张牌是原牌堆的第t+1张牌。由题意的,新牌堆第k+1张牌上的值为k+1,由此得原牌堆t+1张牌的值为k+1。a[t]=k+1。因为b[k]=t+1,所以a[b[k]-1]=b[k]。

        为了保证空间更优,使用循环数组的方式,来实现在牌堆底加牌的步骤。

代码:

/*
 * 一副从1到n的牌,每次从牌堆顶取一张放桌子上,再取一张放牌堆底,直到手机没牌,最后桌子上的牌是从1到n有序,设计程序,输入n,输出牌堆的顺序数组
 */
public class changeIndexAndValue{
	public static void algorithm(int n)
	{
		int a[] = new int[n];
		int b[] = new int[n];
		int t=n-1;//新牌堆顶数组索引
		int u=0;//原牌堆顶数组索引
		int m=0;//原牌堆底数组索引,为了实现循环数组
		for(int k=0;k<n;k++)//给每个原牌堆的牌打上标记
		{
			a[k]=k+1;
		}
		for(int l=0;l<n;l++) //共l个步骤
		{
			
			b[t]= a[u];//将当前原牌堆顶的牌放入新牌堆顶
			t--;//新牌堆顶上移
			a[m]=a[(u+1)%n];//将当前原牌堆顶的牌放入原牌堆底,利用循环数组,节省空间。
			m++;
			u=(u+2)%n;
		}
		for(int h=0;h<n;h++)//按顺序输出新牌堆里,原牌堆的标记,同时计算出原牌堆对应的数值
		{
			System.out.print(b[h]);
			a[b[h]-1]= h+1;
		}
		System.out.println();
		for(int p=0;p<n;p++)
		{
			System.out.print(a[p]);
		}
	}
	public static void main(String[] args) {
		changeIndexAndValue.algorithm(5);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41175067/article/details/80914660