如題:如何在亂序數(shù)組中尋找最大值和最小值,要求比較次數(shù)盡可能小。
思路:如果是單純的遍歷一邊,會對每一個元素與存儲的最大值和最小值進(jìn)行比較,比較次數(shù)為2n,考慮到如果比最大的元素大,也就不用跟最小的元素進(jìn)行對比了,比較次數(shù)會略小于2n。
顯然這種思路過于常規(guī),一般面試官也不會希望得到這種答案。
正確的思路是類似于快速排序的分組方式,對數(shù)組從兩頭進(jìn)行分組,即第0個元素與第n-1個元素進(jìn)行對比,大的放a組,小的放b組;然后第一個與n-2進(jìn)行對比........直到兩邊序號重合,比較次數(shù)為n/2,這時,最大的數(shù)肯定在a組里,最小的數(shù)肯定在b組。然后再在a組里尋找最大值,再在b組里尋找最小值,分別都是n/2次比較,一共使用3/2n次比較就搞定啦。
上代碼:
void findMaxandMinNumber(int nums[], int count) {
//分組
int i = 0;
for (; i < (count - i - 1); i++) {
if (nums[i]<nums[count-1-i]) {
//交換位置
int tem = nums[i];
nums[i] = nums[count-i-1];
nums[count-i-1] = tem;
}
}
int sep = 0;
int middle = 0;
if (i == count-i-1) {
//奇數(shù)
sep = count/2+1;
middle = nums[count/2];
} else {
//偶數(shù)
sep = count/2;
}
//大的一組
int max = nums[0];
for (int j=1; j<count/2-1; j++) {
if (nums[j]>max) {
max = nums[j];
}
}
//小的一組
int min = nums[sep];
for (int j=sep+1; j<count-1; j++) {
if (nums[j]<min) {
min = nums[j];
}
}
//與middle進(jìn)行對比
if (i == count-i-1) {
if (middle>max) {
max = middle;
}
if (middle<min) {
min = middle;
}
}
printf("max = %d, min = %d", max, min);
}