Java集合与手动循环 - 编码挑战/采访最佳实践

时间:2017-06-06 19:27:50

标签: java algorithm optimization collections

对于编码挑战/访谈以及优化,使用馆藏是否合适?例如,检查以下程序的回文运行时间

    import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Palindrome {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        String str = sc.next();

        if(isPalindrome(str)) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }

        if(isPalindromeUsingSet(str)) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }

    }

    public static boolean isPalindrome(String str) {
        final long startTime = System.nanoTime();
        final long duration;
        for (int i=0;i<str.length()/2;i++) {
            if(str.charAt(i) != str.charAt(str.length() -1 -i)) {
                duration = System.nanoTime() - startTime; 
                System.out.println("isPalindrome - " + duration);
                return false;
            } 
        }
        duration = System.nanoTime() - startTime; 
        System.out.println("isPalindrome - " + duration);

        return true;
    }

    public static boolean isPalindromeUsingSet(String str) {
    final long startTime = System.nanoTime();
    final long duration;
    Set<Character> charSet = new HashSet<>();
    for (int i=0;i<str.length()/2;i++) {
        if(charSet.add(str.charAt(i)) == false) {
            duration = System.nanoTime() - startTime; 
            System.out.println("isPalindromeUsingSet - " + duration);
            return false;
        } else {
            charSet.remove(str.charAt(i));
        }
    }
    duration = System.nanoTime() - startTime; 
    System.out.println("isPalindromeUsingSet - " + duration);
    return true;
}

}

计算的运行时间如下所示。

AMANAPLANACANALPANAMA
isPalindrome - 7788
YES
isPalindromeUsingSet - 745473
YES

我的几个问题是:

  1. 因此,java集合在各种CRUD中大多数都是安全且通用的 操作,为什么不使用它们?
  2. 为了编写更优化的解决方案,我应该寻找一个循环 执行,使用了很多O(1)数据结构?
  3. 我学习优化代码的方法:

    1. 对于每个编码问题,解决我粗略的java和数据方式 结构。
    2. 以后去研究最佳解决方案,计算时间和复杂度,逐步适应我的解决方案。
    3. 背景: 我已经编写java几年了。现在学习拼图,算法和时间复杂度的编码,以进行更大的访谈!

      赞赏任何好的方向。

      谢谢

2 个答案:

答案 0 :(得分:1)

我们来看看HashSet.add实现:

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

在内部,HashSet使用HashMap

现在,我们来看看HashMap.put方法实现:

public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

我们可以注意到,从计算机上讲,将注册表放入地图是一项“艰巨的任务”。有一个:

  • 哈希算法
  • for循环
  • 添加条目执行方法
  • 等......

因此,如果执行时间在您的场景中是一个问题,手动循环它是比Java集合更好的选择。

现在,就可读性和可维护性而言,收藏是最佳选择。

答案 1 :(得分:1)

在理解两个函数的比较错误后关闭。