diff --git a/Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution.go b/Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution.go index 2317566..b9407b4 100644 --- a/Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution.go +++ b/Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution.go @@ -1,5 +1,6 @@ package challenge3rotationcount + /* Given an array of numbers which is sorted in ascending order and is rotated ‘k’ times around a pivot, find ‘k’. @@ -45,3 +46,42 @@ func countRotations(arr []int) int { return 0 } + +// +// How do we find the rotation count of a sorted and rotated array that has duplicates too? +// ref: https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/ +// +func countRotations2(arr []int) int { + var ( + start = 0 + end = len(arr) - 1 + ) + + for start < end { + mid := start + (end-start)/2 + if mid < end && arr[mid] > arr[mid+1] { + return mid + 1 + } + if mid > start && arr[mid-1] > arr[mid] { + return mid + } + + if arr[start] == arr[mid] && arr[mid] == arr[end] { + // 这种情况需要判断start,end是否是最小值 + if arr[start] > arr[start+1] { + return start + 1 + } + start++ + if arr[end-1] > arr[end] { + return end + } + end-- + } else if arr[start] < arr[mid] || (arr[start] == arr[mid] && arr[mid] > arr[end]) { + start = mid + 1 + } else { + end = mid - 1 + } + } + + return 0 +} diff --git a/Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution_test.go b/Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution_test.go index a8c5393..dc265bb 100644 --- a/Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution_test.go +++ b/Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution_test.go @@ -1,6 +1,8 @@ package challenge3rotationcount -import "testing" +import ( + "testing" +) func Test_countRotations(t *testing.T) { type args struct { @@ -24,3 +26,29 @@ func Test_countRotations(t *testing.T) { }) } } + +func Test_countRotations2(t *testing.T) { + type args struct { + arr []int + } + tests := []struct { + name string + args args + want int + }{ + {"case1", args{[]int{10, 15, 1, 3, 8}}, 2}, + {"case2", args{[]int{4, 5, 7, 9, 10, -1, 2}}, 5}, + {"case3", args{[]int{1, 3, 8, 10}}, 0}, + {"case4", args{[]int{10, 1, 3, 8, 9}}, 1}, + {"case5", args{[]int{3, 3, 7, 3}}, 3}, + {"case6", args{[]int{3, 3, 3, 3, 7}}, 0}, + {"case7", args{[]int{10, 1, 10, 10, 10}}, 1}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := countRotations2(tt.args.arr); got != tt.want { + t.Errorf("countRotations2() = %v, want %v", got, tt.want) + } + }) + } +}