每日一题26:求逆序对数目与求和

求逆序对问题与解决方案原理

在一个数列中,如果规定从小到大为正序,那么如果排在后面的某个元素比前面的某一个元素小,那么就称这两个数构成一个逆序对,例如,数列5,4,3,2,1中,任一个数都与它前面的数构成逆序对,这个序列中一共就有1+2+3+4=10个逆序对,数列23541中有5个逆序对,那么任给定一个数列,如何知道有多少个逆序对呢?简单的方法是将每个元素与它后面的元素比较,然后就可以累加出总的逆序对数目,这种算法的复杂度是O(n^2)。另一种比较快的方法是利用归并排序,得到的算法复杂度为O(nlgn)。想法是这样的,归并算法合并阶段,分界点前后两个子序列都是有序的,当我们把两个子序列写会结果数组时,如果左子序列剩余的第一个元素小于或等于右子序列剩余的第一个元素,那么就选择左子序列的第一个元素写会结果数组中,否则选择右子序列剩余元素的第一个元素写会结果数组。被选择的元素小于或等于它所在子序列剩余的元素,也小于另一个子序列剩余的元素,但不同的是,如果选择的是左子序列的元素,那么这个元素在为合并之前是位于当前剩余元素的前面的,所以不存在逆序对,如果选择的是右子序列的元素,那么这个元素在为合并之前是位于当前剩余元素的后面的,所以它存在逆序对,那么是多少呢,答案是左子序列当前还剩余的元素个数。在一次合并过程中的情况已经讨论清楚了,把所有的合并阶段联合起来,就可以看成是我们对每一个元素从距离它比较近的地方开始寻找它的逆序对数,但不是一次就计算完它的逆序对数,而是有间隔地计算,另一点考虑是,在一次合并过程中所涉及的元素序列之前的序列中的元素位置的交换并不会影响这个元素的逆序对,因为它们位置变化了,但还是在这个元素之前。而在一个元素后面的元素本来就不参与这个元素逆序对的计算。因此,上面的算法恰好能计算出所有的逆序对数目。

求和问题与解决方案原理

给定一个数列,在给定一个sum,判断在数列中是否存在两个数之和是sum,这样的数对有几个。简单方法是对每一个元素到它后面的元素中查找是否有另一个数与之相加之和等于sum,如果找到这样的一个数,标记这个数已经使用过,然后在考察其他元素,时间复杂度是O(n^2)。如果序列是有序的问题就会简单点了,设两个指针分别指向数组的首位元素,然后将两个指针指向的元素相加,如果相加之和大于sum,那么后指针向前推荐一个位置,如果相加之和小于sum,前指针向后推进一个位置,如果相加之和等于sum,增加一个满足条件的数对,然后后指针向前推进一个位置,前指针向后推进一个位置(假设用过的值不能重复使用),继续需找下一对满足条件的数对,知道两个指针相遇或交叉。

代码与结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值