zoukankan      html  css  js  c++  java
  • 如何高效检查一个数组中是否包含某个值?

    转载地址:http://www.diguage.com/archives/112.html

    1、不同的实现方式

    1) 使用List

    public static boolean useList(String[] arr, String targetValue) {
           return Arrays.asList(arr).contains(targetValue);
    }
    2) 使用Set

    public static boolean useSet(String[] arr, String targetValue) {
          Set<String> set = new HashSet<String>(Arrays.asList(arr));
          return set.contains(targetValue);
    }
    3) 使用循环:

    public static boolean useLoop(String[] arr, String targetValue) {
        for (String s : arr) {
            if (s.equals(targetValue)) {
                return true;
            }
        }
        return false;
    }
    4) 使用Arrays.binarySearch

    public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
        int a = Arrays.binarySearch(arr, targetValue);
        if (a > 0) {
            return true;
        } else {
            return false;
        }
    }

    2、时间复杂度

    使用如下代码来粗略比较不同实现间的时间复杂度。虽然不是很精确,但是思路确实正确的。我们将看看数组在有5、1k、10k个元素的情况下的不同表现。

    public static void main(String[] args) {
        String[] arr = new String[]{"CD", "BC", "EF", "DE", "AB"};
    
        // use list
        long startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useList(arr, "A");
        }
        long endTime = System.nanoTime();
        long duration = endTime - startTime;
        System.out.println("useList:  " + duration / 1000000);
    
        // use set
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useSet(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useSet:  " + duration / 1000000);
    
        // use loop
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useLoop(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useLoop:  " + duration / 1000000);
    
        // use Arrays . binarySearch ()
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useArraysBinarySearch(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useArrayBinary:  " + duration / 1000000);
    }
    结果:

    useList:  12
    useSet:  65
    useLoop:  2
    useArrayBinary:  7

    使用大一点的数组(1k个元素):

    int length = 1000;
    String[] arr = new String[length];
    
    Random s = new Random();
    for (int i = 0; i < length; i++) {
        arr[i] = String.valueOf(s.nextInt());
    }
    结果:
    useList:  115
    useSet:  2010
    useLoop:  97
    useArrayBinary:  9
    使用更大一点的元素(10k个元素):

    int length = 10000;
    String[] arr = new String[length];
    
    Random s = new Random();
    for (int i = 0; i < length; i++) {
        arr[i] = String.valueOf(s.nextInt());
    }

    结果:

    useList:  1678
    useSet:  25609
    useLoop:  1802
    useArrayBinary:  10
    从上面的结果可以清晰看到,使用简单循环的相比使用其他集合操作更高效。很多很多开发人员使用第一种方法,但是它并不是最高效的。将数组转化成其他的任何集合类型都需要先将所有元素读取到集合类中,才能对这个集合类型做其他的事情。

    当使用Arrays.binarySearch()方法时,数组必须是排好序的。如果数组不是排好序的,则不能使用这个方法。

    事实上,如果你真的需要高效地检查一个数组或者集合中是否包含一个值,一个排好序的数组或者树可以达到O(log(n))的时间复杂度,HashSet甚至能达到O(1)的时间复杂度。


  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/archermeng/p/7537228.html
Copyright © 2011-2022 走看看