腾讯2017年实习招聘在线笔试题(求逆序对)

题目:在一个排序中,如果任意一对元素前面的值比后面的值大,我们就说这个排序有一个逆序,一个排序中逆序的总数为逆序数。例:DBBAC的逆序数为6(DB、DB、DA、DC、BA、BA)。实现一个函数,计算输入字符串(长度为1-1024)的逆序数,输入字符串只会出现ABCD这4个字符,大小关系为D>C>B>A,要求时间复杂度为O(n)。

看到这个问题其实第一反应这不就是个典型的求逆序对数嘛,网上一大堆,目前网上公认的最优的解法就是采用归并的思想(所谓最优是个人认为……),所以笔试的时候就想都没想直接用归并的方式写了,后来写完才发现题目中要求时间复杂度为O(n),仔细想了一下貌似归并的方法的时间复杂度是O(nlogn),不可能啊,从没见过O(n)的时间复杂度能实现求逆序数的,仔细一看,字符串中只有A B C D 四个字符,然后就反应过来了,然而并没有时间了……

后来跟同学讨论了一下,发现这个题其实很简单,因为题目要求只有A B C D四个字母,所以我们就可以申请一个只有4个元素的整形数组记为int a[4]。下标0 1 2 3 分别对应A B C D,然后从前向后遍历输入的字符串,遍历的同时给下标为当前字母的元素加1,例如:首先设置一个sum记为逆序对数,第一个字母是D,那么我就给array[3] + 1,在遍历的同时,把所有下标比当前字母大的元素值相加,然后再累加到sum上,这样依次遍历到字符串最后,sum的值就是逆序对数。下面用图解说明一下:

假设输入的字符串是 DBBAC

这里写图片描述

解释一下,从头开始遍历DBBAC
1、读取字符 ‘D’ ,给下标为D(也就是3)的元素+1,同时D也是数组里下标最大的,没有比D大的字母,所以sum不做处理;
2、读取字符 ‘B’ ,给下标为B(也就是1)的元素+1,此时a[1] = 1同时把下标为C 和 D的元素值相加,即a[2]+a[3] = 1,此时sum=1;
3、读取字符 ‘B’ ,给下标为B(也就是1)的元素+1,此时a[1] = 2同时把下标为C 和 D的元素值相加,即a[2]+a[3] = 1,此时sum+=a[2]+a[3],sum = 2;
4、读取字符 ‘A’,给下标为A(也就是0)的元素+1,此时a[0] = 1同时把下标为B C D的元素值相加,即a[1]+a[2]+a[3] = 3,然后累加到sum上,此时sum+=a[1]+a[2]+a[3],sum = 5;
5、读取字符 ‘C’,给下标为C(也就是2)的元素+1,此时a[2] = 1同时把下标为D的元素累加到sum上,即sum+=a[3],此时sum = 6;
由此整个过程结束,只对序列进行了一次遍历,就求出了逆序对数。时间复杂度为O(n)。

不得不说,看清题目很重要,看清题目很重要,看清题目很重要!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值