Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 最低掉期金额_Algorithm - Fatal编程技术网

Algorithm 最低掉期金额

Algorithm 最低掉期金额,algorithm,Algorithm,假设我们得到了1和0的序列(长度n),例如10100100。我们想重新排列它们,所以1跟随每个0,而0跟随每个1——但最后可能会有一些0或1剩下,所以我们的序列将变成10101000。假设有k数量的1和n-k数量的0,所以我们需要有min(n,n-k)组10(或01)然后剩下的 我们可以做一个操作——交换两个选定的元素。我们需要计算将序列重新排列为给定顺序的最小交换量-例如,我们只需要一次交换(在索引4和5之间,从0索引),就可以正确地重新排列。对于0101011111或10101000000我

假设我们得到了1和0的序列(长度
n
),例如
10100100
。我们想重新排列它们,所以
1
跟随每个
0
,而
0
跟随每个
1
——但最后可能会有一些
0
1
剩下,所以我们的序列将变成
10101000
。假设有
k
数量的
1
n-k
数量的
0
,所以我们需要有
min(n,n-k)
10
(或
01
)然后剩下的

我们可以做一个操作——交换两个选定的元素。我们需要计算将序列重新排列为给定顺序的最小交换量-例如,我们只需要一次交换(在索引
4
5
之间,从
0
索引),就可以正确地重新排列。对于
0101011111
10101000000
我们需要
0
交换


你知道怎么计算吗?实际上,任何复杂性都会受到影响-我不知道如何做到这一点。

根据您的示例,我假设您的多余字符必须出现在字符串的右侧。这意味着前面的字符必须交替。这只为最终字符串提供了两种可能的解决方案。在你给出的情况下,这些将是

10101000
01010100
整个算法很简单:生成这两个序列(
k
0与
k
1交替),并附加
n-k
extra。将每一个字符与原始字符进行比较,看看哪一个字符的移位量较小。识别这些对并交换。例如,使用上述方法:

10100100  original
10101000  candidate
--------
....!!..  two differences, one swap

10100100  original
01010100  candidate
--------
!!!!....  four differences, two swaps

您使用第一个候选项,位置4和5已经标识。

将字符串转换为整数集合:

("10100100".toList).map (_.toInt-'0')
= List(1, 0, 1, 0, 0, 1, 0, 0)
使用索引将其压缩:

.zipWithIndex
List((1,0), (0,1), (1,2), (0,3), (0,4), (1,5), (0,6), (0,7))
对于模,找到索引(0,1,2…),我们期望的值,(010…)a是字符串值,b是可能的,交替值01,c是字符串中的索引

.map {case (a,b)=> (a, b%2, b)}
List((1,0,0), (0,1,1), (1,0,2), (0,1,3), (0,0,4), (1,1,5), (0,0,6), (0,1,7))
筛选符合预期的人(对顺序相反的人也一样,a!=b):

按交替值分组,以便以后计数:

.groupBy {case (a,b,c)=> b}
Map(1 -> List((1,1,5)), 0 -> List((0,0,4), (0,0,6)))
获取长度并计数:

.map {case (a, b) => (a, b.length)}
Map(1 -> 1, 0 -> 2)
忽略1和0作为标识符,只需进行计数:

.map (i => (i._2))
List(1, 2)
由于我们只能对1执行掉期交易,其中我们有相应的0,反之亦然,因此取两者中的最小值:

"10100100".toList).map (_.toInt-'0').zipWithIndex.map {case (a,b)=> (a, b%2, b)}.filter {case (a,b,c) => a==b }.groupBy {case (a,b,c)=> b}.map {case (a, b)=> (a, b.length)}.map (i => (i._2)).min
1
最后,我们不需要c值,它只是用来跟踪发生了什么。以下是不带c的版本,以1而不是0开头:

("10100100".toList).map (_.toInt-'0').zipWithIndex.map {case (a,b)=> (a, b%2)}.filter {case (a,b) => a!=b }.groupBy {_._2}.map {case (a, b)=> (a, b.length)}.map (i => (i._2)).min
2

这两个值(1,2)中的最小值就是解决方案。

您有没有尝试过这个问题?即使是蛮力算法?想到的简单解决方案是
而(未排序){swap(随机元素1,随机元素2)}
,这可能在宇宙热死之前完成,也可能不完成;-)您是否必须检查10101000或01010100(第一个示例)是否需要更少的掉期?或者你必须为一些有效的解决方案寻找最少的交换吗?思考('1')的位置和模运算能帮助你吗?O(2n):解析字符串以计算0,1的数量。重写字符串,从第一个字符开始,然后交替0,1,直到一组字符用完,然后用剩余的字符结束字符串。不需要交换。@AJD发布您的答案,这是正确的方法,但唯一的操作是交换?如果我们可以
list
zip
group
,那么我在上面的评论中提到的字符串解决方案也是可能的(因为字符串只是一个有序的字符列表)。好吧,我想这是要做的实际操作,而不是在哪里执行交换的推理。“你知道如何计算吗?”-所以问题是,如何计算互换。
("10100100".toList).map (_.toInt-'0').zipWithIndex.map {case (a,b)=> (a, b%2)}.filter {case (a,b) => a!=b }.groupBy {_._2}.map {case (a, b)=> (a, b.length)}.map (i => (i._2)).min
2