算法----两数之和
算法是一个很有意思的事情,尤其是,当你看到比你想法更好的算法的时候,真的是,有些人思维独特,很聪明。把复杂的问题,用很简单的代码写出来。
反正,算法是思想的交流。思想的交流,一般都会碰撞出火花。
总结:
1.我喜欢先写思路,再写代码。思路很重要,实现很简单。
有时候,你的思路的优化,决定了你的算法的效率。所以,一定要多斟酌几次。可以找到自己思路里面,可以优化的点。
2.自己写出来,要和别人比一下效率。不要闭门造车。
3.我学到了通过双层索引 解决问题的思路。
算法题目:
两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
我的解决办法:
public static int[] twoSum(int[] numbers, int target) {
int[]result = {0,0};
int length = numbers.length;
if (length <2) {
return result;
}
int endIndex = length -1;
int startIndex = 0;
//找到比target 小的第一个数 需要考虑有负数的情况
// while (endIndex >=0 && numbers[endIndex] >= target){
// endIndex--;
// }
// // 该数组没有满足条件的
// if (endIndex == 0) {
// return result;
// }
//从最小的那个数 往前遍历循环 如果当前的这个数 和前面的数都不符合 该数pass
//遍历的时候,当前的数和在遍历的数 如果比要找的数大 后面直接不用遍历
//直接遍历下一个数
//优化点: 1. 一层for 循环就可以 不要想的太复杂 2.遍历的时候,当前的数和在遍历的数 如果比要找的数小 前面的直接不用遍历
out:for (; endIndex > 0; endIndex--) {
for (; startIndex <endIndex; startIndex++) {
int sum = numbers[endIndex] + numbers[startIndex];
if (sum == target) {
break out;
}else if (sum > target){
//结束层循环
// i = endIndex;
break;
}
}
}
//最后返回两个索引
result[0] = ++startIndex;
result[1] = ++endIndex;
return result;
}
网上写的比我优秀的代码,我用了两个for循环,但是别人用一个循环,两个index 搞定:
class Solution {
public int[] twoSum(int[] numbers, int target) {
int left = 0;
int right = numbers.length - 1;
while (left < right) {
if (numbers[left] + numbers[right] > target) {
right--;
} else if (numbers[left] + numbers[right] == target){
return new int[] {left + 1, right + 1};
} else {
left++;
}
}
return null;
}
}
网上最快的方法:
网上最快的 通过2分查找 确实 两个数只和 要么是两个一样的中间数 要么是一个比他大的数 一个比他小的数加起来的
因为二分法查找的两个数的合 所以二分法查找的一定在第一个数的右边 所以下面numbers[load - 1] 里面的load - 1 不可能是-1
class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] ans = new int[2];
int half = target / 2;
int load = Arrays.binarySearch(numbers, half) >= 0 ? Arrays.binarySearch(numbers, half)
: Arrays.binarySearch(numbers, half) * -1 - 1;
if (numbers[load - 1] + numbers[load] == target) {
ans[0] = load;
ans[1] = load + 1;
return ans;
}
if (numbers[load] + numbers[load + 1] == target) {
ans[0] = load + 1;
ans[1] = load + 2;
return ans;
}
int start = load - 1;
int end = load;
while (start >= 0 && end < numbers.length) {
if (numbers[start] + numbers[end] > target) {
start--;
} else if (numbers[start] + numbers[end] < target) {
end++;
} else {
ans[0] = start + 1;
ans[1] = end + 1;
return ans;
}
}
return null;
}
}
加油吧,少年
泰山崩于前而色不变的曹新雨,抱歉