1.一拍脑门,耗时最长算法O(n^2) ==> 爆破算法
2.二拍脑门,从减法变加法,仍然是时间复杂度O(n^2) ==> 爆破算法
3.耗时思考:
- 双层 for 循环
- 最惨情况:给定数组的最后2个数值,如果有序是不是就会快点?二分法
- 如何加速查找,加速命中
4.耗时改进:
- 单层 for 循环
- 加速查找 ==> int[hash]
- 加速命中 ==> 减法补数概念,target - a = a.补数 = b (a.值不被关注)
5.优化结果:HashMap<a.补数,a.数组索引>
class Solution {
public static void main(String[] args) {
int[] nums = new int[]{2, 7, 3, 3, 11, 15};
int target = 6;
int[] result = twoSum(nums, target);
int[] result2 = twoSum2(nums, target);
int[] result1 = twoSum1(nums, target);
System.out.println(result[0] + "," + result[1]);
System.out.println(result1[0] + "," + result1[1]);
System.out.println(result2[0] + "," + result2[1]);
}
/**
* 执行用时 :3 ms, 在所有 java 提交中击败了98.42%的用户
* 内存消耗 :36.9 MB, 在所有 java 提交中击败了93.40%的用户
*
* @param nums 数组
* @param target 目标值
* @return 两数索引数组
*/
private static int[] twoSum(int[] nums, int target) {
//1.两两求和 改良
//目标:加速
// ① 双层 for 循环 ??必要吗
// ② 数据排序 ? 不也是一层for循环?
// ③ 加速命中 ?
//产物:哈希Map<a的target补数,a的index>
// 单层 for 循环
// 插入数值时 ==> 建立索引 ==> HashMap
// 所查找目标:两数值索引index1,index2 ——> 两数值无所谓,只要证明其关系 ——> 存入数值a-替换->存入a对target补数
//3.数值b 与 数值a的HashMap<a.补数 , a.index> 进行包含计算 b == a.补数 == target - a
HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
if (hash.containsKey(nums[i]))
return new int[]{hash.get(nums[i]), i};
hash.put(target - nums[i], i);
}
return new int[]{};
}
/**
* 执行用时 :50 ms, 在所有 java 提交中击败了21.74%的用户
* 内存消耗 :37.3 MB, 在所有 java 提交中击败了90.40%的用户
*
* @param nums 数组
* @param target 目标值
* @return 两数索引数组
*/
private static int[] twoSum2(int[] nums, int target) {
//2.两两求和,if 和==target
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length; j++) {
int res = nums[i] + nums[j];
if (i == j) continue;
else if (res == target)
return new int[]{i, j};
}
}
return new int[]{};
}
/**
* 执行用时 :123 ms, 在所有 java 提交中击败了5.02%的用户
* 内存消耗 :37.6 MB, 在所有 java 提交中击败了86.00%的用户
*
* @param nums 数组
* @param target 目标值
* @return 两数索引数组
*/
private static int[] twoSum1(int[] nums, int target) {
//1.target-nums[i],if 差值==nums[j]
for (int i = 0; i < nums.length; i++) {
int cha = target - nums[i];
for (int j = 0; j < nums.length; j++) {
if (cha == nums[j]) {
if (i == j) continue;
return new int[]{i, j};
}
}
}
return new int[]{};
}
}