二分查找(search方法)
public int search(int[] nums, int target) {
int left=0;
int right=nums.length-1;
int mid;
while(left<=right){
mid=(left+right)/2;
if(nums[mid]==target){
return mid;
}else if(nums[mid]<target){
left=mid+1;
}else{
right=mid-1;
}
}
return -1;
}
- 算法原理
二分查找是一种在有序数组中查找特定元素的高效算法。其基本思想是将数组分为两半,通过比较中间元素与目标值,逐步缩小搜索范围,直到找到目标值或搜索范围为空。
时间复杂度:O(log n),其中n是数组的长度。每次比较后,搜索范围减半,因此对数级别的复杂度使得二分查找在处理大数据集时非常高效。
空间复杂度:O(1),只需要常数级的额外空间存储指针和中间变量。
2. 代码实现
初始化:定义两个指针left和right,分别指向数组的起始和末尾。
循环条件:while (left <= right),确保搜索范围有效。
计算中间索引:mid = (left + right) / 2,注意这里可以优化为mid = left + (right - left) / 2,避免整数溢出。
比较与更新指针:
如果nums[mid] == target,返回mid。
如果nums[mid] < target,更新left = mid + 1,搜索右半部分。
如果nums[mid] > target,更新right = mid - 1,搜索左半部分。
返回值:如果未找到目标值,返回-1。
3. 常见错误
索引越界:确保在更新指针时,指针始终在数组的有效范围内。
死循环:确保每次循环都能缩小搜索范围,避免无限循环。
原地移除元素(removeElement方法)
public int removeElement(int[] nums, int val) {
int temp=nums.length-1;
int i=0;
while (i<=temp){
if(nums[i]val){
while (temp>-1&&nums[temp]val){
temp--;
}
if(i>temp)break;
nums[i]=nums[temp];
nums[temp]=val;
temp-=1;
}
i++;
}
return i;
}
1.算法原理
原地移除是指在不使用额外数组的情况下,移除数组中所有等于特定值的元素,并返回新数组的长度。通过双指针技术,可以在一次遍历中完成任务。
时间复杂度:O(n),其中n是数组的长度。每个元素最多被访问两次(一次由i指针,一次由temp指针)。
空间复杂度:O(1),只需要常数级的额外空间存储指针。
2. 代码实现
初始化:定义两个指针i和temp,分别指向数组的起始和末尾。
循环条件:while (i <= temp),确保搜索范围有效。
查找和替换:
如果nums[i] == val,从数组末尾找到第一个不等于val的元素,将其移到i位置,并将val移到末尾,更新temp。
如果i > temp,说明后面没有不等于val的元素了,退出循环。
更新指针:i++,继续检查下一个元素。
返回值:返回i,即新数组的长度。
3. 常见错误
索引越界:确保在更新指针时,指针始终在数组的有效范围内。
逻辑错误:确保在替换元素时,temp指针正确更新,避免重复替换或遗漏。
总结
通过实现二分查找和原地移除元素这两个算法,我深刻体会到了算法设计中的关键点,如边界条件处理、指针更新和循环条件控制。这些算法不仅在理论上有重要意义,而且在实际应用中也非常实用。通过不断练习和优化,可以提高编程能力和算法思维。