个人解法
暴力法
从前向后,看是否能找到
target-num[i]
时间复杂度
O
(
n
2
)
O(n^2)
O(n2)
空间
O
(
1
)
O(1)
O(1)
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] ans = new int[2];
for(int i = 0;i < nums.length;++i){
for(int j = i+1;j < nums.length;++j){
if(nums[i]+nums[j]==target){
ans[0] = i;
ans[1] = j;
}
}
}
return ans;
}
}
竟然能过,有点吃惊,感觉该有哈希或者其他做法吧。再想想
题解
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; ++i) {
if (hashtable.containsKey(target - nums[i])) {
return new int[]{hashtable.get(target - nums[i]), i};
}
hashtable.put(nums[i], i);
}
return new int[0];
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/two-sum/solution/liang-shu-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这道题重点在于找到当前元素的补数。
- 暴力法是遍历找,查找过程 O ( N ) O(N) O(N)
- 而把数据放到哈希表中,根据数据内容确定存储位置,当知道数据内容就能知道存储位置,所以可以以 O ( 1 ) O(1) O(1) 时间复杂度找到该元素。
问题
先留着,以后系统学了集合框架解决
HashMap
查找过程HashMap
建立过程
哈希表什么时候都是 O ( 1 ) O(1) O(1) 找到目标数据吗?
正常情况
O
(
1
)
O(1)
O(1) 就能从哈希表中取到数据,有冲突会扫链表,这时不是
O
(
1
)
O(1)
O(1) 取到数据
哈希冲突解决方法
开放定址法
H i = ( H ( k e y ) + d i ) % m H_i=(H(key)+d_i)\%m Hi=(H(key)+di)%m
-
线性探测法
d i = 1 , 2 , . . . , k ( k ≤ m − 1 ) d_i=1,2,...,k(k \le m-1) di=1,2,...,k(k≤m−1)
造成同义词 聚集 在相邻的散列地址,大大降低查找效率
-
平方探测法
d i = 0 2 , 1 2 , − 1 2 , 2 2 , − 2 2 , . . . , k 2 , − k 2 ( k ≤ m 2 ) d_i=0^2,1^2,-1^2,2^2,-2^2,...,k^2,-k^2(k\le \frac{m}{2}) di=02,12,−12,22,−22,...,k2,−k2(k≤2m)
m必须是一个可以表示为 4k+3 的素数
- 避免出现 堆积问题
- 不能探测散列表所有单元,但至少探测一半
-
再散列法
H i = ( H ( k e y ) + i ∗ H a s h 2 ( k e y ) ) % m H_i = (H(key)+i*Hash_2(key))\%m Hi=(H(key)+i∗Hash2(key))%m
初始探测位置H_0=H(key)%m ,i是冲突次数,初始为0
最多经历 m-1 次探测就会遍历表中所有位置,回到 H_0 -
伪随机数法
d i = 伪随机数序列 d_i=伪随机数序列 di=伪随机数序列
拉链法
同义词以链表形式链接到同一单元后