最少交换算法

  被问到这样的一个题目:
You are given a string s containing only the letters 'a' and 'b'. The letters are arranged in a circle, so the last and first characters are adjacent.
You will perform a series of swaps until all the 'a's form one consecutive sequence and all the 'b's form another consecutive sequence. In each swap, you can select any two characters and swap them. Return the minimal number of swaps necessary to reach your goal.

   虽然没有时间编码实现,但还是思考了一段时间。没有严格证明,但自己觉得以下的算法可以满足要求。有时间的话,我会试试的。

   该算法分如下几步(注意字符位置是环形计数的,从0开始):
   1. 置变量Count为0;
   2. 若给定字符串已经连续分类排列,则直接返回Count值;否则Count增1;
   3. 从给定字符串中找出最取长的字母'a'连续串str的起始位置start和结束位置end;
   4. 从起始位置向左找到第一个不在str中的字符'a',记录起始位置到此位置的距离ll;
   5. 从结束位置向右找到第一个不在str中的字符'a',记录起始位置到此位置的距离rl;
   6. 找出离str左端最远的一个字符'a'的位置L,str左端到L位置的距离为l;
   7. 找出离str右端最远的一个字符'a'的位置R,str右端到R位置的距离为r;
   8. Lmax记为l和r中的最大者所对应的距离;
   9. 比较ll和rl大小,
   
   A. ll >= rl时,则用Lmax位置上的字符和end+1的字符交换位置;
   
   B. ll < rl时,则用L位置上的字符和start-1的字符交换位置;
   10. 重复2-10步骤。

   上面说的可能比较啰嗦,举个例子来说明这个算法。假设字符串为'aabbbbabba',按上面的步骤说明,各步结果如下:
   1. Count先置为0
   2. Count=0+1=1
   3. start=9,end=1
   4. ll=((start-6)+10)%10-1=2
   5. rl=((6-end)+10)%10-1=4
   6. L=6, l=((start-6)+10)%10-1=2
   7. R=6, r=((6-end)+10)%10-1=4
   8. max(l,r)=r,所以Lmax=R=6
   9. 因为ll<rl,所以Lmax位置的字符和start-1的字符交换位置,即6和8位置交换,得到aabbbbbbaa
   10. 重复步骤1,发现为所求,返回Count值。

0 1 2 3 4 5 6 7 8 9 0
+-+-+-+-+-+-+-+-+-+-+
|a a b b b b a b b a|
+-+-+-+-+-+-+-+-+-+-+
|a a b b b b b b a a|
+-+-+-+-+-+-+-+-+-+-+
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值