|
@@ -0,0 +1,53 @@
|
|
|
|
+struct Solution;
|
|
|
|
+
|
|
|
|
+impl Solution {
|
|
|
|
+ pub fn find_peak_element(nums: Vec<i32>) -> i32 {
|
|
|
|
+ let n = nums.len();
|
|
|
|
+ if n == 1 { return 0; }
|
|
|
|
+ Self::bs(&nums, n, 0, n-1) as i32
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn bs(nums: &Vec<i32>, n: usize, left: usize, right: usize) -> usize {
|
|
|
|
+ if left == right { return left; }
|
|
|
|
+ if left + 1 == right {
|
|
|
|
+ if nums[left] < nums[right] { return right}
|
|
|
|
+ else { return left; }
|
|
|
|
+ }
|
|
|
|
+ let mid = (left + right) / 2;
|
|
|
|
+ if Self::is_peak(nums, mid, n) { return mid; }
|
|
|
|
+ if nums[mid] < nums[mid+1] {
|
|
|
|
+ Self::bs(nums, n,mid+1, right)
|
|
|
|
+ } else {
|
|
|
|
+ Self::bs(nums, n,left, mid-1)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn is_peak(nums: &Vec<i32>, idx: usize, n: usize) -> bool {
|
|
|
|
+ match idx {
|
|
|
|
+ 0 if nums[0] < nums[1] => true,
|
|
|
|
+ _ if idx + 1 == n && nums[n-1] > nums[n-2] => true,
|
|
|
|
+ _ if nums[idx-1] < nums[idx] && nums[idx] > nums[idx+1] => true,
|
|
|
|
+ _ => false
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#[cfg(test)]
|
|
|
|
+mod tests {
|
|
|
|
+ use super::*;
|
|
|
|
+
|
|
|
|
+ #[test]
|
|
|
|
+ fn test_find_peak_element() {
|
|
|
|
+ let nums = vec![1,2,1,3,5,6,4];
|
|
|
|
+ let res = Solution::find_peak_element(nums);
|
|
|
|
+ assert_eq!(res, 5);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #[test]
|
|
|
|
+ fn test_find_peak_element2() {
|
|
|
|
+ let nums = vec![1,2,3,1];
|
|
|
|
+ let res = Solution::find_peak_element(nums);
|
|
|
|
+ assert_eq!(res, 2);
|
|
|
|
+ }
|
|
|
|
+}
|