Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.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 对于ArrayList,有没有比O(n)更好的搜索方法?_Java_Arraylist_Time Complexity - Fatal编程技术网

Java 对于ArrayList,有没有比O(n)更好的搜索方法?

Java 对于ArrayList,有没有比O(n)更好的搜索方法?,java,arraylist,time-complexity,Java,Arraylist,Time Complexity,我有一个小测验的问题: If input data of randomList are 4 5 1 2 3 4 Results are: pick(4) -> 4 4 pick(1) -> 1 pick(2) -> 2 pick(6) -> there is no value 这些是默认代码,我们可以在任何地方自由放置任何代码: public static void main(String[] args){ List<Integer> randomL

我有一个小测验的问题:

If input data of randomList are 4 5 1 2 3 4
Results are:
pick(4) -> 4 4
pick(1) -> 1
pick(2) -> 2
pick(6) -> there is no value
这些是默认代码,我们可以在任何地方自由放置任何代码:

public static void main(String[] args){
    List<Integer> randomList = new ArrayList<>();
    for(int i = 0; i < 100000000; i++) {
        randomList.add(new Random().nextInt());
    }
    .....
    System.out.println("result = " + pick(new Random().nextInt()));
publicstaticvoidmain(字符串[]args){
List randomList=新建ArrayList();
对于(int i=0;i<100000000;i++){
添加(新的Random().nextInt());
}
.....
System.out.println(“result=“+pick(new Random().nextInt()));
问题是,对于函数pick(),哪种方法比O(n)更有效

这是我的O(n)版本:

static List list2=new ArrayList();
公共静态void main(字符串[]args){
List randomList=新建ArrayList();
对于(int i=0;i<10;i++){
添加(new Random().nextInt(5)+1);
}
list2=随机列表;
System.out.println(“result=“+pick(new Random().nextInt(5)+1));
}
公共静态字符串选取(整数兰德){
字符串结果=”;
System.out.println(“search=“+rand”);
对于(整数s:list2){
如果(s==rand){
结果=结果+“”+兰德;
}
}
返回结果;
}

非常感谢。

如果您使用一个
映射,其中key是您的输入值,value是频率,那么
Map
将在
O(1)
时间中找到一个键。字符串构造将与键的频率成比例。因此,代码可以如下所示:

Map<Integer, Integer> mapList = new HashMap<>();
public static void main(String[] args){
    for(int i = 0; i < 10; i++) {
        int key = new Random().nextInt(5)+1;
        if (mapList.contains(key)) {
            mapList.put(key, mapList.get(key) + 1);
        } else {
            mapList.put(key, 1);
        } 
    }

    System.out.println("result = " + pick(new Random().nextInt(5)+1));
}

public static String pick(int rand) {
    Integer count = mapList.get(rand);
    if (count == null) {
        return "";
    } 
    StringJoiner sj = new StringJoiner(" ");
    for (int i = 0; i < count; i++) {
        sj.add(rand);
    }
    return sj.toString();
}
Map-mapList=newhashmap();
公共静态void main(字符串[]args){
对于(int i=0;i<10;i++){
int key=new Random().nextInt(5)+1;
if(mapList.contains(key)){
mapList.put(key,mapList.get(key)+1);
}否则{
地图列表。放置(键,1);
} 
}
System.out.println(“result=“+pick(new Random().nextInt(5)+1));
}
公共静态字符串选取(整数兰德){
整数计数=mapList.get(rand);
如果(计数=null){
返回“”;
} 
细木工sj=新细木工(“”);
for(int i=0;i
编辑


正如@Pshemo所建议的,使用
StringJoiner
代替StringBuilder,因为它更紧凑,不会为最后一个字符添加冗余空间。

鉴于您的限制,除了O(n)之外,没有更好的搜索算法。原因如下:

  • 您的数据包含0到100000000之间的“随机”值
  • 您希望收集与给定数字匹配的所有值(在您的示例中为4)
  • 您无法对列表进行排序(这将导致额外的O(n*log(n))开销)

唯一可以改进的方法是将数据集移动到不同的数据结构,例如映射。然后,加载数据会受到O(n)惩罚,但之后可以在固定时间内找到值。

在列表上迭代一次以生成(和缓存)怎么样
Map
哪一个将所有相等的值分组?构建过程将花费O(n)个时间,但每个
Map.get(value)
调用都将是O(1)。您的版本不是O(n)。您使用的是二次字符串串联。如果需要多次搜索,可以使用
nlogn
(快速排序)对其进行排序,然后搜索将得到
logn
(二进制搜索)。@AndyTurner啊,我明白了。感谢您注意到所有列表的搜索都有O(n)复杂度。您可以使用包含O(log(n))的树/映射进行插入和搜索,并使用两倍的空间满足您的要求。没问题。顺便说一句
sb.append(“\n”)
可能是不必要的,因为应该由用户自己决定是将返回值打印为单独的行还是一行。顺便说一句,StringJoiner比StringBuilder更好,因为它可以防止在最后一个元素后添加空间。是的,我认为这是目前唯一的方法。还没有找到更好的选择。
Map<Integer, Integer> mapList = new HashMap<>();
public static void main(String[] args){
    for(int i = 0; i < 10; i++) {
        int key = new Random().nextInt(5)+1;
        if (mapList.contains(key)) {
            mapList.put(key, mapList.get(key) + 1);
        } else {
            mapList.put(key, 1);
        } 
    }

    System.out.println("result = " + pick(new Random().nextInt(5)+1));
}

public static String pick(int rand) {
    Integer count = mapList.get(rand);
    if (count == null) {
        return "";
    } 
    StringJoiner sj = new StringJoiner(" ");
    for (int i = 0; i < count; i++) {
        sj.add(rand);
    }
    return sj.toString();
}