LeetCode704 力扣
* 基础二分法
* 考虑如何不让数据溢出,区间如何切换
* LeetCode34 力扣寻找最左区间 和 最右区间,套路和基础二分法类似,就是要在找到target的时候继续向左或者向右移动
package algor.trainingcamp;
/**
* @author lizhe
* @version 1.0
* @description: https://leetcode.cn/problems/binary-search/
*
* 二分法
* @date 2023/4/5 09:45
*/
public class LeetCode704 {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) >> 1);
if(nums[mid] < target){
//值偏小,向右取
left = mid + 1;
}else if(nums[mid] > target){
//偏大,向左取
right = mid - 1;
}else{
return mid;
}
}
return -1;
}
/**
* 找到最左的含义是: 即便找到了目标值,还是需要继续向左寻找(right边界向左)
*/
public int searchLeft(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) >> 1);
if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] > target){
right = mid - 1;
}else{
//即便target值相等 还是需要继续向左
right = mid - 1;
}
}
return left;
}
/**
* 找到最右的含义是: 即便找到了目标值,还是需要继续向右寻找(left边界向右)
*/
public int searchRight(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) >> 1);
if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] > target){
right = mid - 1;
}else{
left = mid + 1;
}
}
return right;
}
public static void main(String[] args) {
LeetCode704 demo = new LeetCode704();
System.out.println(demo.search(new int[]{-1, 0,3, 5, 9, 12}, 3));
}
}
LeetCode 27 力扣
1. 暴力解法: 外层循环遍历数组,如果发现出现需要替换的值,将后续的值均都往前赋值(本意是向前提一位,但是操作上是赋值,需要将末值进行忽略)
2. 双指针: 快指针遍历数组,找到无需移除的元素,慢指针原地更新
package algor.trainingcamp;
/**
* @author lizhe
* @version 1.0
* @description: https://leetcode.cn/problems/remove-element/ 移除元素
* @date 2023/4/5 10:17
*
*/
public class LeetCode27 {
/**
* 1. 暴力做法,当发现存在目标值,将目标值后面的所有数都往前挪一位(需要注意每次数据的长度变化)
*/
public int removeElement(int[] nums, int val) {
int size = nums.length;
for(int i = 0;i < size;i++){
if(nums[i] == val){
for(int j = i + 1;j < size;j++){
nums[j - 1] = nums[j];
}
/**
* 忽略了i--操作,这里简单做一下3,2,2,3的debug
* 由于在代码中做的是'赋值'操作,因此每一次需要对末尾的数进行忽略,使用'i--'进行忽略
* 3,2,2,3 -> 2,2,3,3-> 2,2,3,3(数组情况)
* 3,2,2,3 -> 2,2,3 -> 2,2(有效数据)
*/
i--;
size--;
}
}
return size;
}
/**
* 双指针
* 明确快慢指针的定义
* fast: 寻找新数组的元素
* slow: 遍历旧数组,实时生成新数组 新数组的范围[0, slow]
*/
public int removeElement2(int[] nums, int val){
int slow = 0;
for(int fast = 0;fast < nums.length;fast++){
if(nums[fast] != val){
//实时刷新数组
nums[slow++] = nums[fast];
}
}
return slow;
}
public static void main(String[] args) {
LeetCode27 demo = new LeetCode27();
System.out.println(demo.removeElement2(new int[]{3,2,2,3}, 3));
}
}