704. 二分查找
题目描述
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9 输出: 4 解释: 9 出现在 nums 中并且下标为 4 示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2 输出: -1 解释: 2 不存在 nums 中因此返回 -1
解题思路
直接使用标准库的做法,slice的partition_point没有找到的时候返回数组的长度
#![allow(unused)] fn main() { struct Solution {} impl Solution { pub fn search(nums: Vec<i32>, target: i32) -> i32 { let x = nums.partition_point(|&x| x < target); if x == nums.len() { return -1 } if nums[x] == target { return x as i32 } -1 } } }
手写的二分查找
#![allow(unused)] fn main() { struct Solution {} impl Solution { pub fn search(nums: Vec<i32>, target: i32) -> i32 { let mut left = 0; let mut right = nums.len(); while left < right { let mid = left + (right - left) / 2; if nums[mid] < target { left = mid + 1 } else if nums[mid] > target { right = mid; } else { return mid as i32 } } -1 } } }
学习感想
对区间的定义没有想清楚,区间的定义就是不变量,在操作的过程中 保持不变量
在左闭右闭区间的情况下 由于right 要 -1,所以要考虑right=0 - 1的情况
#![allow(unused)] fn main() { struct Solution {} impl Solution { pub fn search(nums: Vec<i32>, target: i32) -> i32 { let mut left = 0isize; let mut right = nums.len() as isize - 1; while left <= right { let mid = (left + (right - left) / 2) as usize; if nums[mid] < target { left = mid as isize + 1 } else if nums[mid] > target { right = mid as isize - 1; } else { return mid as i32 } } -1 } } }
重写
- 喜欢用左闭右开的区间
- match arm不需要用
,
结尾也是合法的语法 Ordering::Less => { right = mid }
要注意“右开” 又写错了
#![allow(unused)] fn main() { struct Solution {} use std::cmp::Ordering; impl Solution { pub fn search(nums: Vec<i32>, target: i32) -> i32 { let mut left: usize = 0; let mut right: usize = nums.len(); while left < right { let mid: usize = left + (right - left) / 2; let mid_num: &i32 = &nums[mid]; match target.cmp(mid_num) { Ordering::Equal => { return mid as i32 } Ordering::Less => { right = mid } Ordering::Greater => { left = mid + 1 } } } -1i32 } } }
使用rust std
#![allow(unused)] fn main() { struct Solution {} impl Solution { pub fn search(nums: Vec<i32>, target: i32) -> i32 { match nums.binary_search(&target) { Ok(idx) => { idx as i32 } Err(_) => { -1i32 } } } } }
#![allow(unused)] fn main() { struct Solution {} impl Solution { pub fn search(nums: Vec<i32>, target: i32) -> i32 { let idx: usize = nums.partition_point(|&x| x < target); if idx == nums.len() { return -1i32 } if nums[idx] != target { return -1i32 } idx as i32 } } }