我编写了两种方法的代码,以找出LeetCode字符串中的第一个唯一字符。
问题陈述: 给定一个字符串,找到其中的第一个非重复字符并返回其索引。如果不存在,则返回-1。
示例测试用例:
s =“ leetcode”返回0。
s =“ loveleetcode”,返回2。
方法1(O(n))(如果我错了,请纠正我):
class Solution {
public int firstUniqChar(String s) {
HashMap<Character,Integer> charHash = new HashMap<>();
int res = -1;
for (int i = 0; i < s.length(); i++) {
Integer count = charHash.get(s.charAt(i));
if (count == null){
charHash.put(s.charAt(i),1);
}
else {
charHash.put(s.charAt(i),count + 1);
}
}
for (int i = 0; i < s.length(); i++) {
if (charHash.get(s.charAt(i)) == 1) {
res = i;
break;
}
}
return res;
}
}
方法2(O(n ^ 2)):
class Solution {
public int firstUniqChar(String s) {
char[] a = s.toCharArray();
int res = -1;
for(int i=0; i<a.length;i++){
if(s.indexOf(a[i])==s.lastIndexOf(a[i])) {
res = i;
break;
}
}
return res;
}
}
在方法2中,我认为复杂度应为O(n ^ 2),因为indexOf在此处以O(n * 1)执行。
但是,当我在LeetCode上执行这两个解决方案时,方法2的运行时间为19毫秒,方法1的运行时间为92毫秒。为什么会这样?
我假设LeetCode对最佳,最差和平均情况下的小和大输入值进行测试。
更新:
我知道以下事实:对于某些n <n1,O(n ^ 2算法)的性能更好。在这个问题中,我想了解为什么在这种情况下会发生这种情况。即方法1的哪一部分使其变慢。
LeetCode链接到问题
对于非常短字符串如单角色作成的成本HashMap
,重新调整其大小,查找条目,而装箱和拆箱的char
成Character
威力遮荫的成本String.indexOf()
,这可能是考虑热和JVM无论哪种方式,内联。
另一个原因可能是RAM访问的成本。随着更多的HashMap
,Character
并Integer
参与查找的对象可能有必要对从RAM额外的访问。单次访问时间约为100
ns,这可能会加起来。
看看 Bjarne Stroustrup:为什么要避免使用链表 。本讲座说明了性能与复杂性并不相同,内存访问可能成为算法的杀手er。
这段Haskell代码在使用
我正在解决以下问题: null 输入:Array arr是一个非空的唯一整数列表,范围在1到1,000,000,000之间,大小N在1到1,000,000之间 输出:一个数组,其中每个索引i包含一个整数,表示ARR[i]的最大相邻子数组数 示例:arr=[3,4,1,6,2]输出=[1,3,1,5,1] 计算从1到N的每个i的g[i]是一种很有希望的方法,但我们仍然需要考虑如何尽可能有效地这样做。
问题内容: 我刚刚开始学习数据结构,并且在进行数组插入时想知道为什么数组插入的时间复杂度为O(n)而不是O(n + 1)? 在最佳情况下,当插入在最后时,时间复杂度为O(1)。我想我们正在考虑1插入元素,因为这里没有元素被移动。在最坏的情况下,假设我们必须移动n个元素然后插入新元素,那么时间时间复杂度是否应该为O(n + 1)?n用于移动元素,1用于插入。 非常感谢您的帮助。 问题答案: O(n)
问题内容: java.util.Random源代码的第294行说 为什么是这样? 问题答案: 该描述并不完全准确,因为0不是2的幂。更好的说法是 当n是2的幂或2的幂的负数或零时。 如果n是2的幂,则二进制中的n是单个1,后跟零。-n为2的补数是倒数+ 1,因此位排成一行 要了解其工作原理,请将二进制补码视为逆+ 1。 因为当您添加一个得到两个的补码时,您会一直进行到一个。 如果n不是2的幂,则结
null 在一个视频教程中,作者提到暴力方法是,阅读另一个答案,一个人认为是,另一个人认为是 强力是还是?更重要的是,您能说明您对蛮力方法执行了哪些分析以知道它是吗?