1. 数组中重复的数字
题目描述:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2
思路:
从头到尾依次扫描这个数组中的每个数字。当扫描到下标为i的数字时,首先比较这个数字(用m表示)是不是等于i。如果是,接着扫描下一一个数字。如果不是,再拿它和第m个数字进行比较。如果它和第m个数字相等,就找到了-个重复的数字(该数字在下标为i和m的位置都出现了)。如果它和第m个数字不相等,就把第i个数字和第m个数字交换,把m放到属于它的位置。接下来再重复这个比较、交换的过程,直到我们发现一个重复的数字。
以数组{2, 3, 1,0,2, 5, 3}为例来分析找到重复数字的步骤。数组的第0个数字(从0开始计数,和数组的下标保持一致)是2,与它的下标不相等,于是把它和下标为2的数字1交换。交换之后的数组是{1,3,2, 0,2,5,3}。、此时第0个数字是1,仍然与它的下标不相等,继续把它和下标为1的数字3交换,得到数组{3, 1,2,0,2,5,3}。接下来继续交换第0个数字3和第3个数字0,得到数组{0,1,2, 3,2,5,3}。此时第0数字的数值为0,接着扫描下一个数字。在接下来的几个数字中,下标为1、2、3的三个数字分别为1、2、3,它们的下标和数值都分别相等,因此不需要做任何操作。接下来扫描到下标为4的数字2。由于它的数值与它的下标不相等,再比较它和下标为2的数字。注意到此时数组中下标为2的数字也是2,也就是数字2在下标为2和下标为4的两个位置都出现了,因此找到一个重复的数字。
代码实现:
/** |
2. 构建乘积数组
题目描述:
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素$B[i]=A[0]A[1]…A[i-1]*A[i+1]…*A[n-1]$。不能使用除法。
思路:
用矩阵的方式,先计算左下三角,再计算右上三角。根据图来分析即可。
代码实现:
package Arr; |
3. 二维数组的查找
题目描述:
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:
利用二维数组由上到下,由左到右递增的规律,那么选取右上角的元素a[row] [col]与target进行比较,
当target小于元素a[row] [col]时,那么target必定在元素a所在行的左边,即col–;
当target大于元素a[row][col]时,那么target必定在元素a所在列的下边,即row++;
代码实现:
package Arr; |
4. 数组中只出现一次的数字
题目描述:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路:
当只有一个数出现一次时,我们把数组中所有的数,依次异或运算,最后剩下的就是落单的数,因为成对儿出现的都抵消了。
依照这个思路,我们来看两个数(我们假设是AB)出现一次的数组。我们首先还是先异或,剩下的数字肯定是A、B异或的结果,这个结果的二进制中的1,表现的是A和B的不同的位。我们就取第一个1所在的位数,假设是第3位,接着把原数组分成两组,分组标准是第3位是否为1。如此,相同的数肯定在一个组,因为相同数字所有位都相同,而不同的数,肯定不在一组。然后把这两个组按照最开始的思路,依次异或,剩余的两个结果就是这两个只出现一次的数字。
所以,只于k位上是1的异或,就把其中一组的落单的那个异或出来了。此外a^b=d 则a^d=b满足结果的互换。知道异或的结果和其中一个,可以求得另一个。
代码实现:
/** |
5. 和为S的两个数
题目描述:
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
代码实现:
/** |
6. 和为S的连续正数序列
题目描述:
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列?
代码实现:
package Arr; |
解法二:
/** |
7. 调整数组顺序使奇数位于偶数前面
题目描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
代码实现:
/** |
8. 数组中出现次数超过一半的数字
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
代码实现:
/** |
9. 连续子数组的最大和
题目描述:
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
代码实现:
/** |
10. 把数组排成最小的数
题目描述:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路:
考虑到大数问题,先将整型数组转换成String数组,然后将String数组排序,最后将排好序的字符串数组拼接出来。关键就是制定排序规则。 排序规则如下: 若ab > ba 则 a > b, 若ab < ba 则 a < b, 若ab = ba 则 a = b;
代码实现:
/** |
11. 数组中的逆序对
题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
示例1
输入1,2,3,4,5,6,7,0
输出7
代码实现:
/** |
12. 数字在排序数组中出现的次数
题目描述:
统计一个数字在排序数组中出现的次数。
代码实现:
/** |
13. 旋转数组的最小数字
题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:
利用二分法,找到中间的数,然后和最左边的值进行比较,若大于最左边的数,则最左边从mid开始,若小于最右边值,则最右边从mid开始。若左中右三值相等,则取mid前后值中较小的数。
代码实现:
/** |