赞
踩
题目链接:leetcode704-二分查找, leetcode27-移除元素
注意事项:开闭区间
如果右闭,则right=len(nums)-1, for left <= right {}, right=mid-1
如果右开,则right=len(nums), for left < right {}, right=mid
左开右闭合: [left, right]
func search(nums []int, target int) int { left, right := 0, len(nums)-1 mid := 0 for left <= right { mid = ((right - left) >> 1) + left if nums[mid] < target { // 说明target在mid右边,mid向右边移动 left = mid + 1 } else if nums[mid] > target { // 说明target在mid左边,mid向左边移动 right = mid - 1 } else { return mid } } return -1 }
左闭右开:[left, right)
func search(nums []int, target int) int { left, right := 0, len(nums) mid := 0 for left < right { mid = ((right - left) >> 1) + left if nums[mid] < target { // 说明target在mid右边, mid右边移动 left = mid + 1 } else if nums[mid] > target { // 说明target在mid左边,mid左边移动 right = mid } else { return mid } } return -1 }
左开右闭合: [left, right]
之所以使用i32是因为当mid为0时, mid-1会报错(Vector的索引是usize类型)
pub fn search(nums: Vec<i32>, target: i32) -> i32 { let (mut left, mut right, mut mid) = (0, (nums.len() - 1) as i32, 0); while left <= right { mid = ((right - left) >> 1) + left; if nums[mid as usize] < target { // 说明target在右区间 left = mid+1; } else if nums[mid as usize] > target { // 说明target在左边区间 right = mid -1 ; } else { return mid as i32; } } return -1; }
左闭右开:[left, right)
pub fn search(nums: Vec<i32>, target: i32) -> i32 { let (mut left, mut right, mut mid) = (0usize, nums.len() - 1, 0usize); while left < right { mid = ((right - left) >> 1) + left; if nums[mid] < target { // 说明target在右区间 left = mid+1; } else if nums[mid] > target { // 说明target在左边区间 right = mid; } else { return mid as i32; } } return -1; }
数组的长度是固定的,无法进行删除,所谓的元素删除也只是将目标val移动到数组的末尾作为无效的值,同时对数组中有效值的数量进行标识,如数组所允许访问的索引范围为[0, 有效值的数量)。
双指针法,不再关系无效的val,让有效的val从索引为0开始重组数组(无效的值会被覆盖,不再关心)
如果不想无效的val被覆盖,可以参考相向双指针法,将无效的val全都移动到数组的尾部
func removeElement(nums []int, val int) int {
idx, numLen := 0, len(nums)
for fast := 0; fast < numLen; fast++ {
if nums[fast] == val {
continue
}
nums[idx] = nums[fast]
idx++
}
return idx
}
相向双指针法,将无效的val全都移动到数组的尾部, 但是数组中的值的顺序会发生变化
基本思路:
func removeElement(nums []int, val int) int { left, right := 0, len(nums)-1 for left <= right { // left指向val的位置 for left <= right && nums[left] != val { left++ } // right指向非val的位置 for left <= right && nums[right] == val { right-- } // 如果移动之后依旧满足left < right, 则交换left和right所指向的值 if left > right { break } nums[left], nums[right] = nums[right], nums[left] left++ right-- } return left }
双指针法
pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 {
let mut slow = 0usize;
for fast in (0..nums.len()) {
if nums[fast] == val {
continue
}
nums[slow] = nums[fast];
slow += 1;
}
slow as i32
}
相向双指针
pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 { let (mut left, mut right) = (0 , nums.len() as i32 - 1); while left <= right { // left指向val的位置 while left <= right && nums[left as usize] != val { left += 1; } // right指向非val的位置 while left <= right && nums[right as usize] == val { // 使用uize,这里可能会报错 right -= 1; } if left > right { break } // 交换值 (nums[left as usize], nums[right as usize]) = (nums[right as usize], nums[left as usize]); left += 1; right -= 1; } left }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。