Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我怎样才能加速我下面的多数元素问题集算法?_Java_Arrays_Algorithm_Data Structures - Fatal编程技术网

Java 我怎样才能加速我下面的多数元素问题集算法?

Java 我怎样才能加速我下面的多数元素问题集算法?,java,arrays,algorithm,data-structures,Java,Arrays,Algorithm,Data Structures,所以,我必须为我的数据结构课程作业写一个算法。我已经使用Java解决了以下问题集 问题:-让我们考虑一个数组中的5个元素的数字序列。 元素数-5 数组元素-2,2,3,9,2 多数元素算法指出,如果一个元素出现超过n/2次,那么它就是数组中的多数元素。因此,我的程序应该输出1(表示找到多数元素),0(未找到多数元素) 根据上面的问题-2在数组中出现了3次,这意味着n/2次(5/2=2(整数,忽略小数)+1=3) 所以,我被要求写一个算法来解决这个问题。选项为分治(即将数组分成两半,在两半中寻

所以,我必须为我的数据结构课程作业写一个算法。我已经使用Java解决了以下问题集

问题:-让我们考虑一个数组中的5个元素的数字序列。 元素数-5 数组元素-2,2,3,9,2

  • 多数元素算法指出,如果一个元素出现超过n/2次,那么它就是数组中的多数元素。因此,我的程序应该输出1(表示找到多数元素),0(未找到多数元素)
根据上面的问题-2在数组中出现了3次,这意味着n/2次(5/2=2(整数,忽略小数)+1=3)

所以,我被要求写一个算法来解决这个问题。选项为分治(即将数组分成两半,在两半中寻找多数元素,然后得到答案) 另一种选择是使用两个for循环扫描数组中的元素,最后获得多数元素。这就是我试过的。我浏览了评分器,但我的程序超过了时间限制。有人能提出建议吗。谢谢

Java代码:-

import java.util.*;

import java.io.*;

public class MajorityElement {
    private static int getMajorityElement(int[] a, int left, int right) {

        int  count = 1;

        int num = a.length/2 + 1;
        Arrays.sort(a);
        if (left == right) {
            return -1;
        }
        if (left + 1 == right) {
            return a[left];
        }

        else
        {



            for(int i=0;i<a.length;i++)
            {
                for(int j=i+1;j<a.length;j++)
                {
                    if(a[i]==a[j])
                    {
                        count++;

                    }
                }

                if(count>1)
                {

                    if(count>=num)
                    {
                        return 1;

                    }
                    i = i + count-1;
                    count = 1;
                }

            }
            return -1;
        }
    }

    public static void main(String[] args) {
        FastScanner scanner = new FastScanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        if (getMajorityElement(a, 0, a.length) != -1) {
            System.out.println(1);
        } else {
            System.out.println(0);
        }

    }
    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream stream) {
            try {
                br = new BufferedReader(new InputStreamReader(stream));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }
    }
}
import java.util.*;
导入java.io.*;
公共类多数元素{
私有静态int getMajorityElement(int[]a,int左,int右){
整数计数=1;
int num=a.length/2+1;
数组。排序(a);
如果(左==右){
返回-1;
}
如果(左+1==右){
返回一个[左];
}
其他的
{
for(int i=0;i=num)
{
返回1;
}
i=i+计数-1;
计数=1;
}
}
返回-1;
}
}
公共静态void main(字符串[]args){
FastScanner=新的FastScanner(System.in);
int n=scanner.nextInt();
int[]a=新的int[n];
对于(int i=0;i
双for循环方法基本上就是这样:

在没有多数元素的情况下,这肯定会花费太长时间,因为它需要n^2个比较,其中n是列表中的元素数。不要那样做。你可以先排序,就像一位对你的问题发表评论的人所说的那样,这将允许你提前一点进行排序,但是你仍然有排序的开销,然后是一些扫描。这看起来像(未经测试,因为它是由您编写的):

将上述代码视为伪代码,因为它未经测试


更多关于多数元素的信息,但都是用Python编写的,所以可能没有帮助

双for循环方法基本上就是这样:

在没有多数元素的情况下,这肯定会花费太长时间,因为它需要n^2个比较,其中n是列表中的元素数。不要那样做。你可以先排序,就像一位对你的问题发表评论的人所说的那样,这将允许你提前一点进行排序,但是你仍然有排序的开销,然后是一些扫描。这看起来像(未经测试,因为它是由您编写的):

将上述代码视为伪代码,因为它未经测试


更多关于多数元素的信息,但都是用Python编写的,所以可能没有帮助

我觉得你的两个选择都不好。您描述的问题是流式算法中的一个标准问题(您有一个巨大的(可能无限的)数据流),您必须从这个流计算一些统计数据,通过这个流一次

它可以通过使用。我不懂Java,但这里是我的解释和几行python代码,您肯定可以将其转换为Java


多数元素是出现在数组大小一半以上的元素。这意味着多数元素的出现次数比所有其他元素的总和还要多,或者如果您计算出现多数元素的次数,然后减去所有其他元素的数目,您将得到一个正数

因此,如果你计算某个元素的数量,减去所有其他元素的数量,得到数字0,那么你的原始元素就不能是多数元素。这是正确算法的基础:

有两个变量,计数器和可能元素。迭代流,如果计数器为0-覆盖可能的元素并初始化计数器,如果数字与可能的元素相同-增加计数器,否则减少计数器。Python代码:

def majority_element(arr):
    counter, possible_element = 0, None
    for i in arr:
        if counter == 0:
            possible_element, counter = i, 1
        elif i == possible_element:
            counter += 1
        else:
            counter -= 1

    return possible_element
很明显,该算法是
O(n)
,在
O(n)
之前有一个非常小的常数(如3)。另外,看起来空间复杂度是
O(1)
,因为我们只初始化了三个变量。问题在于,其中一个变量是一个计数器,它可能会增长到
n
(当数组由相同的数字组成时)。和存储号码<
Arrays.sort(a); // actually I hate this because it mutates your array (BAD!)
for (int i = 0; i < a.length; i++) {
    int count = 0;
    for (int j = i; i < j.length; j++) {
        if (a[j] == a[i]) {
            count++;
            if (count > a.length / 2) {
                return true;
            }
         } else if (a[j] > a[i]) {
             break; // no more to count
         }
    }
}
return false;
count = 0
for (int x: a) {
    if (count == 0) {
        candidate = x;
    }
    if (x == candidate) {
        count += 1
    } else {
        count -= 1
    }
}
count = 0;
for (int x: a) if (a==candidate) count++;
return count > a.length / 2;
def majority_element(arr):
    counter, possible_element = 0, None
    for i in arr:
        if counter == 0:
            possible_element, counter = i, 1
        elif i == possible_element:
            counter += 1
        else:
            counter -= 1

    return possible_element