文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。
这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。
相关文章:
- LeetCode:55. Jump Game(跳远比赛)
- Leetcode:300. Longest Increasing Subsequence(最大增长序列)
- LeetCode:560. Subarray Sum Equals K(找出数组中连续子串和等于k)
1.一个数组中有相同的值,找出相同的值中出现的第一个;
package binarysearch;
import org.junit.Test;
/**
* @author zhangyu
* 寻找有相同的值中,下标最小的那一个
*
*/
public class SearchFirstEqualNumber {
@Test
public void fun() {
int arr[] = {1, 2, 3, 4, 4, 4, 4, 6, 8};
int k = 4;
int index = searchFirstEqualNumer(arr, k);
System.out.println(index);
}
private int searchFirstEqualNumer(int[] arr, int k) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = low + (high - low)/2;//防止下标越界
if (arr[mid] > k) {
high = mid - 1;
} else if (arr[mid] < k) {
low = mid + 1;
} else {
if (mid == 0 || arr[mid - 1] != k) {
return mid;
} else {
high = mid - 1;
}
}
}
return -1;
}
}
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
我来稍微解释一下这段代码。a[mid] 跟要查找的 k的大小关系有三种情况:大于、小于、等于。对于 a[mid]>value 的情况,我们需要更新 high= mid-1;对于 a[mid]<value 的情况,我们需要更新 low=mid+1。这两点都很好理解。那当 a[mid]=value 的时候应该如何处理呢?
如果我们查找的是任意一个值等于给定值的元素,当 a[mid] 等于要查找的值时,a[mid] 就是我们要找的元素。但是,如果我们求解的是第一个值等于给定值的元素,当 a[mid] 等于要查找的值时,我们就需要确认一下这个 a[mid] 是不是第一个值等于给定值的元素。
如果 mid 等于 0,那这个元素已经是数组的第一个元素,那它肯定是我们要找的;如果 mid 不等于 0,但 a[mid] 的前一个元素 a[mid-1] 不等于 k,那也说明 a[mid] 就是我们要找的第一个值等于给定值的元素。
如果经过检查之后发现 a[mid] 前面的一个元素 a[mid-1] 也等于 k,那说明此时的 a[mid] 肯定不是我们要查找的第一个值等于给定值的元素。那我们就更新 high=mid-1,因为要找的元素肯定出现在 [low, mid-1] 之间。
2.一个数组中有相同的值,找出相同的值中出现的最后一个;
package binarysearch;
import org.junit.Test;
/**
* @author zhangyu
* @Description: 寻找相同的值,坐标最大的那一个
*
*/
public class SearchLastEqualNumber {
@Test
public void fun() {
int arr[] = {1, 2, 3, 4, 4, 4, 4, 6, 8};
int k = 4;
int index = searchLastEqualNumber(arr, k);
System.out.println(index);
}
private int searchLastEqualNumber(int[] arr, int k) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2;//这样做是为了房子溢出
if (arr[mid] > k) {
high = mid - 1;
} else if (arr[mid] < k) {
low = mid + 1;
} else {
if (mid == high - 1 || arr[mid + 1] != k) {
return mid;
} else {
low = mid + 1;
}
}
}
return -1;
}
}
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
如果 a[mid] 这个元素已经是数组中的最后一个元素了,那它肯定是我们要找的;如果 a[mid] 的后一个元素 a[mid+1] 不等于 k,那也说明 a[mid] 就是我们要找的最后一个值等于给定值的元素。
如果我们经过检查之后,发现 a[mid] 后面的一个元素 a[mid+1] 也等于 k,那说明当前的这个 a[mid] 并不是最后一个值等于给定值的元素。我们就更新 low=mid+1,因为要找的元素肯定出现在 [mid+1, high] 之间。
源码github地址: