小程序员的趣味题(一)

1.在排序数组中,找出某整数出现的次数


问题定义:给定一个整数数组arr,数组中元素的个数是n,数组arr已经排好序,要在arr中找到某个某个整数x出现的次数,比如arr[] = {1,2,2,3,5,10},找到2的出现次数就是2。

问题分析相必看到有序数组的字样,想到利用二分应该是很顺利成章的事了。我们可以利用二分搜索求出x在arr中出现的第一个位置lo和最后一个位置hi,然后计算hi-lo+1的值就是x在arr出现的次数了,当然也有可能x并没有在arr中出现过,这时hi和lo都等于-1。时间复杂度是两个二分的复杂度:2*O(log n)。看看代码是怎么实现的吧!!

相关代码:

View Code

小结:有人也提到了这样解法,即:先利用二分找到x在arr中出现的第一个位置lo,然后从lo下一位置开始向后直到下标达到n-1或者找到不等于x的情况结束,每前进一步,x出现的次数加 1,这样也能求出x在arr中出现的次数,但是不要忘了这种情况,即arr = {1,1,1,1,1,1},然后x = 1,那么这时利用这种方法的时间复杂度就是O(n+log n) 了。也就是说在最坏的情况下,时间复杂度太高。

 

2.去掉字符串中多余的空格


问题描述:给定一个字符串数组,要求去掉首部和尾部的所有空格,字符串中间的空格出现1次以上只保留一个空格,比如str[] = “  Wo  shi Vincent  ”,经过处理后应为“Wo shi Vincent”。

问题分析:这是一个简单的字符串处理的问题,显然开头、结尾、和中间的空格处理方式是不一样的,我的思路是遍历一遍字符数组,首先处理开头的空格,方法是:全部删除;然后是字符串中间的空格,方法是:遇到空格,值保留第一个空格;遍历结束后,新串的最后一个字符是空格,就代表是原字符串尾部有空格存在,所以要去掉。如此一来就完事了,值需要遍历一遍,时间复杂度是O(n)。

相关代码:

View Code

 

3.求1024!的结果中末尾有多少个0


问题分析:首先1024!呀,是多么大的一个数呢??想求出来结果然后在看末尾有多少0是不现实的,我们可以分析要求的是:末尾有多少个0。那么的0的个数有什么决定的呢?10 = 2 * 5 ,显然一对(2 , 5)就能凑出一个末尾0,也就是说末尾0的个数是由因子2和5的个数决定的,更确切的说是由因子的个数决定的(考虑一下为什么吧!?),那么1~1024这1024个数中包含多少个因子5呢?显然这1024个数有的包含1个因子5,有的包含两个因子5(5^2 = 25),有得包含三个因子5(5^3 = 125),有的包含4的因子5(5^4 = 625)。那么一共包含多少因子5呢?

包含一个因子5的数有 1024 / 5 = 204 个。

包含两个因子5的数有 1024 / 25 = 40 个。

包含三个因子5的数有 1024 / 125 = 8 个。

包含四个因子5的数有 1024 / 625 = 1 个。

也就是说1~1024这1024个数一共包含因子5的个数是: sum =  204 + 40 + 8 + 1 个。

小结:注意类似的问题可以借鉴这个题的解题思路~~~~~~

 

4.给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数


问题分析:现在给了一个能随机生成1~5的随机函数,怎样利用这个已知条件生成一个1~7的随机函数呢?既然要生成的是随机数那么生成1,2,3,4,5,6,7的概率就应该是一样的。显然现在光生成1~5之间的数就不够了,我们想到应该要加大生成数的范围,并且加大范围的同时还要保证每个数产生的概率一样,于是有这样一种方法用这个表达式来扩大生成数范围:rand5()*5+rand5(),新的数据范围变成:6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30.并且可以看出来这个25个数出现的可能性是一样的,于是我们可以只用6~26之间的21个数变成1~7这7个数,于是就是要每3个数对应一个数,即:

6,7,8对应1

9,10,11对应2

…………

24,25,26对应7

这种变化对应的方式是(6 - 3)/ 3 = 1,(7 - 3) / 3 = 1,(8-3) / 3 = 1.看看代码吧:

相关代码:

View Code
阅读更多
换一批

没有更多推荐了,返回首页