活动地址:CSDN21天学习挑战赛
一.顺序查找
从头到尾遍历每一个元素,直到找到元素为止(遍历)
int sort(int[] nums, int target)
查找成功返回查找目标的下标,查找失败返回-1
算法分析
对给出的数组进行遍历,依次与目标元素进行比较,如果匹配成功则返回当前匹配位置的下标,若遍历完所有元素,都没有找到目标元素,则返回-1表示匹配失败。
代码实现
public int sort(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
// 匹配成功
if (nums[i] == target) return i;
}
// 匹配失败
return -1;
}
复杂度分析
- 时间复杂度:显式,该算法的时间复杂度主要取决于for循环,而其需要进行n次比较,所以时间复杂度为O(n)
- 空间复杂度:没有引入新的空间,故空间复杂度为O(1)
二.二分查找
依次比较当前中间的元素(分治)
int sort(int[] nums, int target)
查找成功返回查找目标的下标,查找失败返回-1
算法分析
二分查找利用了分治思想,其可以很大程度的减少查找的时间复杂度,但其只能应用在有序数。其算法核心思想是依次取出当前剩余元素(每次剔除一半)的中间位置与目标元素进行比较。
- 如果等于目标元素,则返回其下标;
- 如果比目标元素大,则再取其右边所有元素值的中间值进行与目标元素的比较;
- 如果比目标元素小,则再取其右边所有元素值的中间值进行与目标元素的比较;
代码实现
public int sort(int[] nums, int target) {
// 待比较元素的起始和截止下标[left, right)
int left = 0;
int right = nums.length;
while(right - left > 0) {
int mid = (right - left) / 2;
if (nums[mid] > target) {
// 向右截取
left = mid + 1;
} else if(nums[mid] < target) {
// 向左截取
right = mid;
} else {
// 匹配成功
return mid;
}
}
// 匹配失败
return -1;
}
这里我们设计right为nums.length
而不是nums.length - 1
,这样做的好处是right-left就可以代表元素的剩余数量,所以以后涉及到元素数量的计算时最好这样设计,这样设计可以避免出现一些令人抓耳挠腮的问题(如:到底应不应该包含等于)。
复杂度分析
- 时间复杂度:由于数据规模每次都进行减半,也就是说如果是说如果数据规模为n,那么我们最多进行logn次匹配即可概括所有情况,所以时间复杂度为O(logn)
- 空间复杂度:没有引入新的空间,所以为O(1)