- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我知道,这似乎是一个愚蠢的问题,你会期望 size() 在任何集合上的时间复杂度都是 O(1) - 但我发现我的代码中的“优化”需要调用 size() 实际上会减慢速度。
那么,Java 中 Set 的 size() 的时间复杂度是多少?
我的代码是一个递归算法的实现,用于查找图中的最大团(不重要)。基本上,优化只是检查两个 Set 的大小是否相等(这些 Set 以任何一种方式构建),如果它们的大小相等,则只允许再进行一次递归调用(之后停止递归)。
这是我的代码的(简化)版本:
private static void recursivelyFindMaximalCliques(Set<Integer> subGraph, Set<Integer> candidates, Set<Integer> notCandidates) {
boolean noFurtherCliques = false;
Iterator<Integer> candidateIterator = candidates.iterator();
while (candidateIterator.hasNext()) {
int nextCandidate = candidateIterator.next();
candidateIterator.remove();
subGraph.add(nextCandidate);
Set<Integer> neighbors = getNeighbors(nextCandidate);
Set<Integer> newCandidates = calculateIntersection(candidates, neighbors);
Set<Integer> newNotCandidates = calculateIntersection(notCandidates, neighbors);
//if (newCandidates.size() == candidates.size())
// noFurtherCliques = true;
recursivelyFindMaximalCliques(subGraph, newCandidates, newNotCandidates);
//if (noFurtherCliques)
// return;
subGraph.set.remove(nextCandidate);
notCandidates.set.add(nextCandidate);
}
}
我注释掉的行是有问题的行 - 你可以看到他们检查集合 newCandidates 和 candidates 是否相同大小,如果是,递归只允许更深一层。
当取消注释这些行时,代码运行速度会慢大约 10% - 无论使用的集合是 HashSet、TreeSet 还是 LinkedHashSet,都是如此。这是没有意义的,因为这些行确保递归调用更少。
我唯一可以假设的是在集合上调用 size() 需要很长时间。在 Java 中对 Sets 调用 size() 花费的时间是否比 O(1) 长?
编辑
既然有人问了,这里就是calculateIntersection():
private static IntegerSet calculateIntersection(Set<Integer> setA, Set<Integer> setB) {
if (setA.size() == 0 || setB.size() == 0)
return new Set<Integer>();
Set<Integer> intersection = new Set<Integer>(); //Replace this with TreeSet, HashSet, or LinkedHashSet, whichever is being used
intersection.addAll(setA);
intersection.retainAll(setB);
return intersection;
}
第二次编辑如果您愿意,这是完整的代码。我犹豫要不要发布它,因为它又长又讨厌,但有人问了,所以在这里:
public class CliqueFindingAlgorithm {
private static class IntegerSet {
public Set<Integer> set = new TreeSet<Integer>(); //Or whatever Set is being used
}
private static ArrayList<IntegerSet> findMaximalCliques(UndirectedGraph graph) {
ArrayList<IntegerSet> cliques = new ArrayList<IntegerSet>();
IntegerSet subGraph = new IntegerSet();
IntegerSet candidates = new IntegerSet();
IntegerSet notCandidates = new IntegerSet();
for (int vertex = 0; vertex < graph.getNumVertices(); vertex++) {
candidates.set.add(vertex);
}
recursivelyFindMaximalCliques(cliques, graph, subGraph, candidates, notCandidates);
return cliques;
}
private static void recursivelyFindMaximalCliques(ArrayList<IntegerSet> cliques, UndirectedGraph graph,
IntegerSet subGraph, IntegerSet candidates, IntegerSet notCandidates) {
boolean noFurtherCliques = false;
Iterator<Integer> candidateIterator = candidates.set.iterator();
while (candidateIterator.hasNext()) {
int nextCandidate = candidateIterator.next();
candidateIterator.remove();
subGraph.set.add(nextCandidate);
IntegerSet neighbors = new IntegerSet();
neighbors.set = graph.getNeighbors(nextCandidate);
IntegerSet newCandidates = calculateIntersection(candidates, neighbors);
IntegerSet newNotCandidates = calculateIntersection(notCandidates, neighbors);
if (newCandidates.set.size() == candidates.set.size())
noFurtherCliques = true;
recursivelyFindMaximalCliques(cliques, graph, subGraph, newCandidates, newNotCandidates);
if (noFurtherCliques)
return;
subGraph.set.remove(nextCandidate);
notCandidates.set.add(nextCandidate);
}
if (notCandidates.set.isEmpty()) {
IntegerSet clique = new IntegerSet();
clique.set.addAll(subGraph.set);
cliques.add(clique);
}
}
private static IntegerSet calculateIntersection(IntegerSet setA, IntegerSet setB) {
if (setA.set.size() == 0 || setB.set.size() == 0)
return new IntegerSet();
IntegerSet intersection = new IntegerSet();
intersection.set.addAll(setA.set);
intersection.set.retainAll(setB.set);
return intersection;
}
public class UndirectedGraph {
// ------------------------------ PRIVATE VARIABLES ------------------------------
private ArrayList<TreeMap<Integer, Double>> neighborLists;
private int numEdges;
// ------------------------------ CONSTANTS ------------------------------
// ------------------------------ CONSTRUCTORS ------------------------------
public UndirectedGraph(int numVertices) {
this.neighborLists = new ArrayList<TreeMap<Integer, Double>>(numVertices);
this.numEdges = 0;
for (int i = 0; i < numVertices; i++) {
this.neighborLists.add(new TreeMap<Integer, Double>());
}
}
// ------------------------------ PUBLIC METHODS ------------------------------
public void addEdge(int vertexA, int vertexB, double edgeWeight) {
TreeMap<Integer, Double> vertexANeighbors = this.neighborLists.get(vertexA);
TreeMap<Integer, Double> vertexBNeighbors = this.neighborLists.get(vertexB);
vertexANeighbors.put(vertexB, edgeWeight);
vertexBNeighbors.put(vertexA, edgeWeight);
this.numEdges++;
}
public List<Integer> computeCommonNeighbors(int vertexA, int vertexB) {
List<Integer> commonNeighbors = new ArrayList<Integer>();
Iterator<Integer> iteratorA = this.getNeighbors(vertexA).iterator();
Iterator<Integer> iteratorB = this.getNeighbors(vertexB).iterator();
if (iteratorA.hasNext() && iteratorB.hasNext()) {
int nextNeighborA = iteratorA.next();
int nextNeighborB = iteratorB.next();
while(true) {
if (nextNeighborA == nextNeighborB) {
commonNeighbors.add(nextNeighborA);
if (iteratorA.hasNext() && iteratorB.hasNext()) {
nextNeighborA = iteratorA.next();
nextNeighborB = iteratorB.next();
}
else
break;
}
else if (nextNeighborA < nextNeighborB) {
if (iteratorA.hasNext())
nextNeighborA = iteratorA.next();
else
break;
}
else if (nextNeighborB < nextNeighborA) {
if (iteratorB.hasNext())
nextNeighborB = iteratorB.next();
else
break;
}
}
}
return commonNeighbors;
}
// ------------------------------ PRIVATE METHODS ------------------------------
private class EdgeIterator implements Iterator<int[]> {
private int vertex;
private int[] nextPair;
private Iterator<Integer> neighborIterator;
public EdgeIterator() {
this.vertex = 0;
this.neighborIterator = neighborLists.get(0).keySet().iterator();
this.getNextPair();
}
public boolean hasNext() {
return this.nextPair != null;
}
public int[] next() {
if (this.nextPair == null)
throw new NoSuchElementException();
int[] temp = this.nextPair;
this.getNextPair();
return temp;
}
public void remove() {
throw new UnsupportedOperationException();
}
private void getNextPair() {
this.nextPair = null;
while (this.nextPair == null && this.neighborIterator != null) {
while (this.neighborIterator.hasNext()) {
int neighbor = this.neighborIterator.next();
if (this.vertex <= neighbor) {
this.nextPair = new int[] {vertex, neighbor};
return;
}
}
this.vertex++;
if (this.vertex < getNumVertices())
this.neighborIterator = neighborLists.get(this.vertex).keySet().iterator();
else
this.neighborIterator = null;
}
}
}
// ------------------------------ GETTERS & SETTERS ------------------------------
public int getNumEdges() {
return this.numEdges;
}
public int getNumVertices() {
return this.neighborLists.size();
}
public Double getEdgeWeight(int vertexA, int vertexB) {
return this.neighborLists.get(vertexA).get(vertexB);
}
public Set<Integer> getNeighbors(int vertex) {
return Collections.unmodifiableSet(this.neighborLists.get(vertex).keySet());
}
public Iterator<int[]> getEdgeIterator() {
return new EdgeIterator();
}
最佳答案
这取决于实现;例如 HashSet.size()
只是在其内部 hashMap
上调用 size()
返回一个变量;
//HashSet
public int size() {
return map.size();
}
//Hashmap
public int size() {
return size;
}
关于java - Java 中集合的 size() 的时间复杂度是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16682831/
多数元素问题: Given an array of size n, find the majority element. The majority element is the element tha
我有一个简单的问题来找到数组 A 中的第一个唯一元素。但是,令我困扰的是使用不同方法的时间复杂度。到目前为止,我已经尝试过这两种方法。 第一种方法: LinkedHashMap> map = new
STL 中valarray::min 和valarray::max 函数的时间复杂度是多少? 此外,什么是查找各种其他 STL 组件的时间/空间复杂性的良好来源? 最佳答案 O(N) 这些函数不会缓存
我目前正在学习复杂性(或效率,不管你怎么调用它),我在我得到的一本书中读到了它。写了一些我觉得很无意义的东西,我需要一个解释。我试过在线查找,但我没有找到他们给出的这个特定示例的答案。 For an
如何分析算法?是什么让快速排序具有 O(n^2) 的最坏情况性能,而合并排序具有 O(n log(n)) 的最坏情况性能? 最佳答案 这是整个学期的主题。最终,我们讨论的是在算法完成之前必须完成的操作
有谁知道最流行的数据库的 SQL LIKE 运算符的复杂度是多少? 最佳答案 让我们分别考虑三个核心案例。此讨论是特定于 MySQL 的,但也可能适用于其他 DBMS,因为索引通常以类似的方式实现。
Go 编程语言中这个循环的计算复杂度是多少? var a []int for i := 0 ; i doublecap { newcap = cap } else {
我需要创建一个查找函数,其中 (X,Y) 对对应于特定的 Z 值。对此的一个主要要求是我需要尽可能接近 O(1) 复杂度。我的计划是使用 unordered_map。 我通常不使用哈希表进行查找,因为
快速提问,主要满足我对该主题的好奇心。 我正在编写一些带有 SQlite 数据库后端的大型 python 程序,并且将来会处理大量记录,因此我需要尽可能优化。 对于一些功能,我正在通过字典中的键进行搜
Go 编程语言中这个循环的计算复杂度是多少? var a []int for i := 0 ; i doublecap { newcap = cap } else {
我有这个方法: public static int what(String str, char start, char end) { int count=0; for(int i=0;
for (i = 0; i i; j--) //some code that yields O(1) } 我认为上面的代码会产生 n*log(n) 但我看到另一个消息来源说它真的是 n^2
我对 InnoDB 中 OFFSET 的复杂性有疑问。我知道这主要适用于线性复杂性,但如果我在字段上有索引?! 示例: CREATE TABLE `person_rand` ( `p_id` int
我嵌套了一些 if/else 语句,但我想减少它们的开销。 在示例中,我正在评估从哪个下拉列表中单击了 li 项目,以及该 li 项目是否是第一个 (currentIndex === 0)。 代码:
这是我的第一个问题,所以我希望我没有违反任何规则。我终于设法为基数排序算法编写代码,但我想知道我是否做错了。让我觉得我的算法看起来复杂度为 O(n^3),但众所周知,基数排序是一个 O(k.n) 算法
几周前我认识了 big-O 并试图掌握它,但是尽管有很多关于计算时间复杂度的 Material ,但我似乎无法找到如何使算法更高效。 我一直在练习 Codility 中的演示挑战: Write a f
在最近的一次考试中,我们得到了一个函数来计算在未排序的 ArrayList 中出现了多少个 double (不是原始 double,而是一个项目出现两次的次数)。 我正确地确定了 Big O 复杂度为
以下循环的大 O 复杂度是多少: for each vertex u ∈ C do for each vertex v ∈ C and v > u do 我在这里做的是想象以下集合 {
我想对条款进行排序,使每个条款都是下一个条款的大 O √n√logn √n log( n^30) n/〖(logn)〗^2 〖16〗^(log√n) 谁能帮忙找到顺序? 最佳答案 claim :16
我正在尝试计算此选择排序实现的大 O 时间复杂度: void selectionsort(int a[], int n) { int i, j, mini
我是一名优秀的程序员,十分优秀!