Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋
times.
You may assume that the array is non-empty and the majority element always exist in the array.
这道题和《剑指offer》面试题29、《编程之美》2.3是一个类型的。我并没有直接给一个可以AC的解法,因为这道题有一个设定是这个超过数组一半的数(majority number)总是存在。但是事实上数组中并不存在这样一个数。所以我把《剑指offer》的解答搬过来,因为它的解法考虑到了这个问题。
解法1:数组中有一个数字出现的次数超过了一半,也就是说它出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保留两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们保存的数字不同,则次数减1。如果次数为零,我们需要保存下一个数字,并把次数设为1。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么我们要找的数字肯定是最后一次把次数设为1时对应的数字。
bool g_invalid_input = false; bool CheckInvalidArray(int* numbers, int len) { g_invalid_input = fasle; if (numbers == NULL || len <= 0) g_invalid_input = true; return g_invalid_input; } bool CheckMoreThanHalf(int* numbers, int len, int candidate) { int times = 0; for (int i = 0; i < len; i++) if (numbers[i] == candidate) times++; if (times * 2 < len) { g_invalid_input = true; return fasle; } return true; } int MoreThanHalf(int* numbers, int len) { if (CheckInvalidArray(numers, len)) return 0; int candidate = numbers[0]; int times = 1; for (int i = 1; i < len; i++) { if (times == 0) { candidate = numbers[i]; times = 1; } else { if (candidate == numbers[i]) times++; else times--; } } if(!MoreThanHalf(numbers, len, candidate)) return 0; return candidate; }
解法二:数组中有一个数字出现的次数超过了数组长度的一半。如果把这个数组排序,那么排序之后位于数组中间的数字一定就是那个出现次数超过长度一半的数字。
bool g_invalid_input = false; bool CheckInvalidArray(int* numbers, int len) { g_invalid_input = fasle; if (numbers == NULL || len <= 0) g_invalid_input = true; return g_invalid_input; } bool CheckMoreThanHalf(int* numbers, int len, int candidate) { int times = 0; for (int i = 0; i < len; i++) if (numbers[i] == candidate) times++; if (times * 2 < len) { g_invalid_input = true; return fasle; } return true; } int Partition(int *numbers, int start, int end) { int pivot = numbers[end]; int p = start - 1; int j = p; for (; j < end; j++) { if (numbers[j] <= pivot) { swap(a[++p], a[j]); } } swap(a[++p], a[end]); return p; } int MoreThanHalf(int* numbers, int len) { if (CheckInvalidArray(numbers, len)) return 0; int k = len / 2; int start = 0; int end = len - 1; int pos = Partition(numbers, start, end); while (pos != k) { if (pos > k) { end = pos - 1; pos = Partition(numbers, start, end); } else { start = pos + 1; pos = Partition(numbers, start, end); } } int candidate = numbers[k]; if (CheckMoreThanHalf(numbers, len, candidate)) candidate = 0; return candidate; }