From 4cb7c2ac94536f4bfebac1765d96fb0f56c55325 Mon Sep 17 00:00:00 2001 From: Zhaowei Date: 2018年12月20日 11:30:06 +0800 Subject: [PATCH 1/2] find first and last position of element in sorted array --- README.md | 1 + ...ast_position_of_element_in_sorted_array.go | 139 ++++++++++++++++++ ...osition_of_element_in_sorted_array_test.go | 64 ++++++++ src/README.md | 1 + 4 files changed, 205 insertions(+) create mode 100644 src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array.go create mode 100644 src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array_test.go diff --git a/README.md b/README.md index 73171b5..3b39ed3 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ continually updating 😃. ### Binary Search * [704. Binary Search](./src/0704_binary_search/binary_search.go) +* [34. Find First and Last Position of Element in Sorted Array](./src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array.go) *`array;`* *`binary search`* diff --git a/src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array.go b/src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array.go new file mode 100644 index 0000000..e4dc777 --- /dev/null +++ b/src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array.go @@ -0,0 +1,139 @@ +/* +34. Find First and Last Position of Element in Sorted Array +https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ + +Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value. + +Your algorithm's runtime complexity must be in the order of O(log n). + +If the target is not found in the array, return [-1, -1]. +*/ +// time: 2018年12月20日 + +package findfirstandlastpositionofelementinsortedarray + +// binary search +// time complexity: O(logn) +// space complexity: O(1) +func searchRange(nums []int, target int) []int { + lowerIndex := firstOccurance(nums, target) + first := -1 + if lowerIndex != len(nums) && target == nums[lowerIndex] { + first = lowerIndex + } + + upperIndex := lastOccurance(nums, target) + last := -1 + if upperIndex == len(nums) && len(nums)> 0 && target == nums[len(nums)-1] { + last = len(nums) - 1 + } else if upperIndex != len(nums) && upperIndex> 0 && target == nums[upperIndex-1] { + last = upperIndex - 1 + } + return []int{first, last} +} + +func firstOccurance(nums []int, target int) int { + var ( + l int + r = len(nums) + ) + + for l != r { // 夹逼思想 + mid := l + (r-l)/2 + if nums[mid] < target { + l = mid + 1 + } else { + r = mid + } + } + return l +} + +func lastOccurance(nums []int, target int) int { + var ( + l int + r = len(nums) + ) + for l != r { + mid := l + (r-l)/2 + if nums[mid] <= target { + l = mid + 1 + } else { + r = mid + } + } + return l +} + +// double index scan +// Time complexity: O(n) +// Space complexity: O(1) +func searchRange1(nums []int, target int) []int { + var ( + l int + r = len(nums) - 1 + ) + + for l <= r { + flag := false + if nums[l] != target { + l++ + flag = true + } + if nums[r] != target { + r-- + flag = true + } + if !flag { + break + } + } + if r < l { + return []int{-1, -1} + } + return []int{l, r} +} + +// binary search + linear scan +// Time complexity: O(logn) ~ O(n) +// Space complexity: O(1) +func searchRange2(nums []int, target int) []int { + var ( + l int + r = len(nums) - 1 + tmp = -1 + ) + + for l <= r { + mid := l + (r-l)/2 + if nums[mid] == target { + tmp = mid + break + } + if nums[mid] < target { + l = mid + 1 + } else { + r = mid - 1 + } + } + if -1 == tmp { + return []int{-1, -1} + } + l = tmp + r = tmp + for true { + if l> 0 && nums[l-1] == target { + l-- + } else { + break + } + } + for true { + if r < len(nums)-1 && target == nums[r+1] { + r++ + } else { + break + } + } + return []int{l, r} +} diff --git a/src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array_test.go b/src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array_test.go new file mode 100644 index 0000000..fe8bdef --- /dev/null +++ b/src/0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array_test.go @@ -0,0 +1,64 @@ +package findfirstandlastpositionofelementinsortedarray + +import ( + "reflect" + "runtime" + "testing" +) + +func TestSearchRange(t *testing.T) { + type arg struct { + nums []int + target int + } + + testCases := []arg{ + arg{ + nums: []int{5, 7, 7, 8, 8, 10}, + target: 8, + }, + arg{ + nums: []int{5, 7, 7, 8, 8, 10}, + target: 6, + }, + arg{ + nums: []int{1}, + target: 1, + }, + arg{ + nums: []int{}, + target: 0, + }, + arg{ + nums: []int{2, 2}, + target: 2, + }, + arg{ + nums: []int{1}, + target: 0, + }, + } + + expected := [][]int{ + {3, 4}, + {-1, -1}, + {0, 0}, + {-1, -1}, + {0, 1}, + {-1, -1}, + } + + testFuncs := []func([]int, int) []int{ + searchRange, + searchRange1, + searchRange2, + } + + for _, testFunc := range testFuncs { + for index, testData := range testCases { + if res := testFunc(testData.nums, testData.target); !reflect.DeepEqual(res, expected[index]) { + t.Errorf("function %s, expected %v, got %v", runtime.FuncForPC(reflect.ValueOf(testFunc).Pointer()).Name(), expected[index], res) + } + } + } +} diff --git a/src/README.md b/src/README.md index f8aaff4..ed1e628 100644 --- a/src/README.md +++ b/src/README.md @@ -9,6 +9,7 @@ |0020|[Valid Parentheses](0020_valid_parentheses/valid_parentheses.go)|Easy|*`string;`* *`stack`*| |0021|[Merge Two Sorted Lists](0021_merge_two_sorted_lists/mergeTwoLists.go)|Easy|*`linked list`*| |0025|[Reverse Nodes in k-Group](./0025_reverse_nodes_in_k_group/reverse_node_k_group.go)|Hard|*`linked list`*| +|0034|[ Find First and Last Position of Element in Sorted Array](0034_find_first_and_last_position_of_element_in_sorted_array/find_first_and_last_position_of_element_in_sorted_array.go)|Medium|*`binary search`*| |0061|[Rotate List](./0061_rotate_list/rotate_list.go)|Medium|*`linked list`*| |0062|[Unique Paths](./0062_unique_paths/unique_paths.go)|Medium|*`recursion;`* *`memory search;`* *`dynamic programming`*| |0063|[Unique Paths 2](./0063_unique_paths_2/unique_paths2.go)|Medium|*`recursion;`* *`memory search;`* *`dynamic programming`*| From 56b06f823393b1068c42221f1c0e2aad6e7fd525 Mon Sep 17 00:00:00 2001 From: Zhaowei Date: 2018年12月20日 11:59:00 +0800 Subject: [PATCH 2/2] fix set.go bug, add test for set.go --- utils/set.go | 4 +-- utils/set_test.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 utils/set_test.go diff --git a/utils/set.go b/utils/set.go index 17eeca3..e441296 100644 --- a/utils/set.go +++ b/utils/set.go @@ -33,8 +33,8 @@ func (s Set) Size() int { } // Clear 清空集合 -func (s Set) Clear() { - s = make(Set) +func (s *Set) Clear() { + *s = make(Set) } // Equal 判断两个set是否相等 diff --git a/utils/set_test.go b/utils/set_test.go new file mode 100644 index 0000000..e0d4d89 --- /dev/null +++ b/utils/set_test.go @@ -0,0 +1,69 @@ +package utils + +import ( + "testing" + "unsafe" +) + +func TestEmptyStruct(t *testing.T) { + if unsafe.Sizeof(Exists) != 0 { + t.Error("Exists size must be zero.") + } +} + +func TestContains(t *testing.T) { + set := NewSet(3, 4) + set.Add(5) + if set.Contains(3) != true { + t.Error("should contains 4.") + } + + if set.Contains(6) != false { + t.Error("should not contains 6.") + } +} + +func TestSize(t *testing.T) { + set := NewSet(3, 4) + set.Add(5) + if set.Size() != 3 { + t.Error("size should be 3.") + } +} + +func TestEqual(t *testing.T) { + set := NewSet(3, 4) + set.Add(5) + + set1 := NewSet(3, 4, 5) + if set.Equal(set1) != true { + t.Error("set should equal with set1.") + } + set1.Add(6) + if set.Equal(set1) == true { + t.Error("set shouldn't equal with set1.") + } +} + +func TestIsSubset(t *testing.T) { + set := NewSet(3, 4) + set.Add(5) + + set1 := NewSet(3, 4, 5, 6) + + if set1.IsSubset(set) == true { + t.Error("set1 shouldn't be set's subset.") + } + + if set.IsSubset(set1) == false { + t.Error("set should be set1's subset.") + } +} + +func TestClear(t *testing.T) { + set := NewSet(3, 4) + set.Clear() + if set.Size() != 0 { + t.Error("set should be clear.") + } +}

AltStyle によって変換されたページ (->オリジナル) /