Browse Source

feat: find_peak_element

Zhang Li 10 months ago
parent
commit
4b900ce769

+ 53 - 0
src/solutions/binary_search/find_peak_element.rs

@@ -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);
+    }
+}

+ 2 - 1
src/solutions/binary_search/mod.rs

@@ -8,4 +8,5 @@ mod median_of_two_sorted_arrays;
 mod binary_tree_preorder_traversal;
 mod binary_tree_postorder_traversal;
 mod find_minimum_in_rotated_array;
-mod find_minimum_in_rotated_array2;
+mod find_minimum_in_rotated_array2;
+mod find_peak_element;