8. 找出整型数组中占比超过一半的数 | 豆包MarsCode AI刷题

92 阅读7分钟

找出整型数组中占比超过一半的数

问题描述

小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。


测试样例

样例1:

输入:array = [1, 3, 8, 2, 3, 1, 3, 3, 3]
输出:3

样例2:

输入:array = [5, 5, 5, 1, 2, 5, 5]
输出:5

样例3:

输入:array = [9, 9, 9, 9, 8, 9, 8, 8]
输出:9

思路

  1. 理解问题

    • 题目要求找到一个数字,它在数组中出现的次数超过数组长度的一半。
    • 这意味着在排序后的数组中,这个数字必然会出现在中间位置。
  2. 数据结构选择

    • 由于我们需要找到一个特定的数字,并且这个数字在排序后的数组中会出现在中间位置,因此我们可以选择对数组进行排序。
  3. 算法步骤

    • 排序:首先对数组进行排序。
    • 取中位数:排序后,数组的中间元素(即中位数)就是我们要找的数字。

具体步骤

  1. 排序数组

    • 使用快速排序(QuickSort)或其他排序算法对数组进行排序。
  2. 获取中位数

    • 排序后,直接取数组的中间元素即可。

需要一点思路提示

要解决这个问题,我们可以利用题目中给出的关键信息:某个数字的出现次数超过了数字总数的一半。这意味着这个数字在排序后的数组中,必然会出现在中间位置(即中位数位置)。

解题思路

  1. 理解问题

    • 题目要求找到一个数字,它在数组中出现的次数超过数组长度的一半。
    • 这意味着在排序后的数组中,这个数字必然会出现在中间位置。
  2. 数据结构选择

    • 由于我们需要找到一个特定的数字,并且这个数字在排序后的数组中会出现在中间位置,因此我们可以选择对数组进行排序。
  3. 算法步骤

    • 排序:首先对数组进行排序。
    • 取中位数:排序后,数组的中间元素(即中位数)就是我们要找的数字。

具体步骤

  1. 排序数组

    • 使用快速排序(QuickSort)或其他排序算法对数组进行排序。
  2. 获取中位数

    • 排序后,直接取数组的中间元素即可。

代码检查

1. 快速排序函数 quickSort

public static void quickSort(int l, int r, int[] num) {
    if (l >= r) return;
    int mid = num[(l + r) / 2]; // Choose pivot element
    int i = l - 1, j = r + 1;
    while (i < j) {
        do i++; while (num[i] < mid);
        do j--; while (num[j] > mid);
        if (i < j) {
            // Swap elements
            int temp = num[i];
            num[i] = num[j];
            num[j] = temp;
        }
    }
    quickSort(l, j, num);
    quickSort(j + 1, r, num);
}
  • 问题

    • quickSort(l, j, num);quickSort(j + 1, r, num); 这两行代码可能会导致栈溢出,特别是在数组已经部分有序的情况下。
    • 选择 mid 作为枢轴元素时,可能会导致不平衡的分区,从而影响性能。
  • 改进建议

    • 可以考虑使用三数取中法(Median-of-Three)来选择枢轴元素,以提高快速排序的性能。
    • 确保分区是平衡的,避免栈溢出。

2. 解决方案函数 solution

public static int solution(int[] list) {
    quickSort(0, list.length - 1, list);
    return list[(list.length - 1) / 2]; // Return the median element
}
  • 问题

    • 代码逻辑是正确的,但可以进一步优化。
  • 改进建议

    • 如果数组已经排序,直接返回中间元素即可。
    • 可以考虑使用更高效的算法,如 Boyer-Moore 投票算法,时间复杂度为 O(n)。

3. 主函数 main

public static void main(String[] args) {
    // Test cases
    System.out.println(solution(new int[]{1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3); // Should print true
}
  • 问题

    • 测试用例是正确的,但可以增加更多的测试用例以确保代码的鲁棒性。
  • 改进建议

    • 增加更多的测试用例,包括边界情况和特殊情况。

总结

你的代码逻辑基本正确,但可以通过以下方式进行改进:

  1. 优化快速排序:使用三数取中法选择枢轴元素,确保分区平衡。
  2. 考虑更高效的算法:如 Boyer-Moore 投票算法,时间复杂度为 O(n)。
  3. 增加测试用例:确保代码在各种情况下都能正确运行。

如果你有任何进一步的问题或需要更多的帮助,请随时告诉我!

  1. 快速排序函数 quickSort java 问题:

quickSort(l, j, num); 和 quickSort(j + 1, r, num); 这两行代码可能会导致栈溢出,特别是在数组已经部分有序的情况下。 选择 mid 作为枢轴元素时,可能会导致不平衡的分区,从而影响性能。 改进建议:

可以考虑使用三数取中法(Median-of-Three)来选择枢轴元素,以提高快速排序的性能。 确保分区是平衡的,避免栈溢出。 2. 解决方案函数 solution java 问题:

代码逻辑是正确的,但可以进一步优化。 改进建议:

如果数组已经排序,直接返回中间元素即可。 可以考虑使用更高效的算法,如 Boyer-Moore 投票算法,时间复杂度为 O(n)。 3. 主函数 main java 问题:

测试用例是正确的,但可以增加更多的测试用例以确保代码的鲁棒性。 改进建议:

增加更多的测试用例,包括边界情况和特殊情况。

快速排序函数 quickSort

问题

  1. quickSort(l, j, num);quickSort(j + 1, r, num); 这两行代码可能会导致栈溢出,特别是在数组已经部分有序的情况下。
  2. 选择 mid 作为枢轴元素时,可能会导致不平衡的分区,从而影响性能。

改进建议

  1. 使用三数取中法(Median-of-Three)来选择枢轴元素

    • 选择数组的第一个元素、中间元素和最后一个元素,然后取这三个元素的中位数作为枢轴元素。这样可以减少不平衡分区的可能性。
  2. 确保分区是平衡的

    • 在递归调用 quickSort 时,确保分区是平衡的,避免栈溢出。
public static void quickSort(int l, int r, int[] num) {
    if (l >= r) return;
    
    // 使用三数取中法选择枢轴元素
    int mid = (l + r) / 2;
    int pivot = medianOfThree(num[l], num[mid], num[r]);
    
    int i = l - 1, j = r + 1;
    while (i < j) {
        do i++; while (num[i] < pivot);
        do j--; while (num[j] > pivot);
        if (i < j) {
            // Swap elements
            int temp = num[i];
            num[i] = num[j];
            num[j] = temp;
        }
    }
    quickSort(l, j, num);
    quickSort(j + 1, r, num);
}

// 辅助函数:三数取中法
private static int medianOfThree(int a, int b, int c) {
    if (a > b) {
        if (b > c) return b;
        else if (a > c) return c;
        else return a;
    } else {
        if (a > c) return a;
        else if (b > c) return c;
        else return b;
    }
}

解决方案函数 solution

问题

代码逻辑是正确的,但可以进一步优化。

改进建议

  1. 如果数组已经排序,直接返回中间元素即可

    • 在排序后,直接返回中间元素。
  2. 考虑使用更高效的算法

    • 如 Boyer-Moore 投票算法,时间复杂度为 O(n)。
public static int solution(int[] list) {
    quickSort(0, list.length - 1, list);
    return list[(list.length - 1) / 2]; // Return the median element
}

主函数 main

问题

测试用例是正确的,但可以增加更多的测试用例以确保代码的鲁棒性。

改进建议

  1. 增加更多的测试用例
    • 包括边界情况和特殊情况。
public static void main(String[] args) {
    // Test cases
    System.out.println(solution(new int[]{1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3); // Should print true
    System.out.println(solution(new int[]{5, 5, 5, 1, 2, 5, 5}) == 5); // Should print true
    System.out.println(solution(new int[]{9, 9, 9, 9, 8, 9, 8, 8}) == 9); // Should print true
    System.out.println(solution(new int[]{1, 1, 1, 1, 1}) == 1); // Should print true
    System.out.println(solution(new int[]{2, 2, 2, 2, 2, 1, 1, 1, 1, 1}) == 1); // Should print true
}

总结

通过上述改进,你的代码将更加健壮和高效。如果你有任何进一步的问题或需要更多的帮助,请随时告诉我!

java题解

import java.util.Arrays;
 
public class Main {
    // Correct quick sort function
    public static void quickSort(int l, int r, int[] num) {
        if (l >= r) return;
        int mid = num[(l + r) / 2]; // Choose pivot element
        int i = l - 1, j = r + 1;
        while (i < j) {
            do i++; while (num[i] < mid);
            do j--; while (num[j] > mid);
            if (i < j) {
                // Swap elements
                int temp = num[i];
                num[i] = num[j];
                num[j] = temp;
            }
        }
        quickSort(l, j, num);
        quickSort(j + 1, r, num);
    }
 
    // Modified solution function, returning the element that appears more than half the time
    public static int solution(int[] list) {
        quickSort(0, list.length - 1, list);
        return list[(list.length - 1) / 2]; // Return the median element
    }
 
    public static void main(String[] args) {
        // Test cases
        System.out.println(solution(new int[]{1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3); // Should print true
    }
}