移位数组 java 小米_小米笔试题--数组移动

1. 题目描述:

给定一个数列,每一次移动可以将数列的某个数移动到某个位置,移动多次后,形成新的数列。定义数列中相邻两两之间的差的绝对值为“移动距离”,定义所有移动距离的总和为“总移动距离”。希望计算出最少的移动次数,使得新数列的“总移动距离”最小。例如原数列为[4,2,7, 6],总移动距离为2+5+1=8.将6移动到7之前,会变成[4,2,6,7],总移动距离为2+4+1=7。

需要编写一个函数,输入为一个int数组表示数列内容,输出为一个int数字,表示最小移动次数。

输入

第一行输入为数组大小,然后依次输入数组元素,如数组[4,2,7,6]。

输出

总移动距离最小的数列之一为[2,4,6,7]

最少移动次数为:2

2. 思路分析

题目定义的“移动距离”为相邻两数之间差的绝对值,要使“总移动距离”最小,移动之后的数据应该为一个有序数列(升序或者降序),这样得到“总移动距离”最小。

最小移动次数:数组长度减去原始数列中最长升序子序列的长度,即得到最小移动次数。

例如:

原始数组 1 6 3 4 8 9 7 2 5 11

最长升序子序列为 1 3 4 8 9 11,长度为6,所以最小移动次数为10 - 6 = 4。

所以题目最终转化为,求给定数列中最长升序子序列的长度,当然也要计算最长降序子序列的长度,然后比较降序和升序的相应的移动次数,得到两者的较小值,即为本题的答案。

3. 最长升序子序列

最简单的方法:动态规划

状态设计:F[i]代表以A[i]结尾的LIS的长度

状态转移:F[i]=max{F[j]+1}(1<=j< i,A[j]< A[i])

边界处理:F[i]=1(1<=i<=n)

时间复杂度:O(n^2)

#include

// 求最长升序子序列的长度

int max(int a, int b)

{

return a > b ? a : b;

}

int main()

{

int a[] = {1,6,4,3,7,8,9,2,5,11};

int b[] = {1,6,3,4,8,9,7,2,5,11};

int dp[10] = {0};

int maxn = 0;

for(int i = 0;i < 9;i++)

{

for(int j = 0;j < i;j++)

{

if(a[j] < a[i]) // a[j] > a[i] 降序

{

maxn = max(dp[j], maxn);

printf("%d, %d\n", a[i], maxn);

}

}

dp[i] = maxn + 1;

}

maxn = dp[0];

for(int i = 0; i < 9; i++)

{

maxn = max(dp[i], maxn);

}

printf("%d", maxn);

getchar();

}

参考

后记

本人水平有限,本文如有错误,欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值