• 数组中出现次数超过一半的数字
    • 题目
    • 解题思路

    数组中出现次数超过一半的数字

    题目

    牛客网

    数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出 2 。如果不存在则输出 0 。

    解题思路

    1. 由于数组的特性,在排序数组中,超过半数的数字一定包含中位数
    2. 通过 partition 方法,借用快排的思想,随机选取一个 key,将数组中小于 key 的移动到 key 的左侧,数组中大于 key 的移动到 key 的右侧
    3. 最终找到中位数的下标,还需要检查中位数是否超过半数
    1. public int MoreThanHalfNum_Solution(int[] array) {
    2. int start = 0, end = array.length - 1;
    3. int mid = array.length / 2;
    4. int index = partition(array, start, end);
    5. if (index == mid) {
    6. return array[index];
    7. }
    8. while (index != mid && start <= end) {
    9. if (index > mid) {
    10. end = index - 1;
    11. index = partition(array, start, end);
    12. } else {
    13. start = index + 1;
    14. index = partition(array, start, end);
    15. }
    16. }
    17. if (checkIsHalf(array, index)) return array[index];
    18. return 0;
    19. }
    20. private boolean checkIsHalf(int[] array, int index) {
    21. if (index < 0) {
    22. return false;
    23. }
    24. int count = 0;
    25. for (int i : array) {
    26. if (array[index] == i) {
    27. count++;
    28. }
    29. }
    30. return count > array.length / 2;
    31. }
    32. private int partition(int[] array, int start, int end) {
    33. if (start >= array.length || start < 0
    34. || end >= array.length || end < 0) {
    35. return -1;
    36. }
    37. int key = array[start];
    38. int left = start, right = end;
    39. while (left < right) {
    40. while (left < right && array[right] >= key) {
    41. right--;
    42. }
    43. if (left < right) {
    44. array[left] = array[right];
    45. left++;
    46. }
    47. while (left < right && array[left] <= key) {
    48. left++;
    49. }
    50. if (left < right) {
    51. array[right] = array[left];
    52. right--;
    53. }
    54. }
    55. array[left] = key;
    56. return left;
    57. }