Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e4604b7

Browse files
binary search (leftmost element) implementation and tests, leetcode Find Target Indices After Sorting Array problem solution
1 parent bf829c5 commit e4604b7

File tree

4 files changed

+163
-0
lines changed

4 files changed

+163
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package binary_search
2+
3+
func BinarySearchLeftmost(a []int, target int) (int, bool) {
4+
l, r := 0, len(a)
5+
for l < r {
6+
m := (l + r) / 2 // similar to floor((l+r)/2) https://go.dev/ref/spec#Arithmetic_operators, see Integer operators
7+
if a[m] < target {
8+
l = m + 1
9+
} else {
10+
r = m
11+
}
12+
}
13+
return l, l < len(a) && a[l] == target
14+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package binary_search
2+
3+
import "testing"
4+
5+
func TestBinarySearchLeftmost(t *testing.T) {
6+
cases := []testCase{
7+
// 0. Regular case
8+
{
9+
arr: []int{3, 4, 5, 6, 7, 7, 8, 9},
10+
target: 7,
11+
expIdx: 4,
12+
expFound: true,
13+
},
14+
// 1. Empty array
15+
{
16+
arr: []int{},
17+
target: 7,
18+
expIdx: 0,
19+
expFound: false,
20+
},
21+
// 2. Single element array doesn't contains element
22+
{
23+
arr: []int{1},
24+
target: 7,
25+
expIdx: 0,
26+
expFound: false,
27+
},
28+
// 3. Single element array contains element
29+
{
30+
arr: []int{7},
31+
target: 7,
32+
expIdx: 0,
33+
expFound: true,
34+
},
35+
// 4. No value (in the middle)
36+
{
37+
arr: []int{-1, -2, 2, 4, 6, 7, 9},
38+
target: 5,
39+
expIdx: 0,
40+
expFound: false,
41+
},
42+
// 5. No value (less than min value in the array)
43+
{
44+
arr: []int{-10, -2, -1, 4, 6, 7, 9},
45+
target: -30,
46+
expIdx: 0,
47+
expFound: false,
48+
},
49+
// 6. No value (more than max value in the array)
50+
{
51+
arr: []int{-10, -2, -1, 4, 6, 7, 9},
52+
target: 50,
53+
expIdx: 0,
54+
expFound: false,
55+
},
56+
// 7. First element
57+
{
58+
arr: []int{-10, -2, -1, 4, 6, 7, 9},
59+
target: -10,
60+
expIdx: 0,
61+
expFound: true,
62+
},
63+
// 8. Last element
64+
{
65+
arr: []int{-12, -10, -2, -1, 4, 6, 7, 9},
66+
target: 9,
67+
expIdx: 7,
68+
expFound: true,
69+
},
70+
}
71+
72+
for caseNum, tc := range cases {
73+
idx, found := BinarySearchLeftmost(tc.arr, tc.target)
74+
if found != tc.expFound {
75+
t.Errorf("case %d error: expecting found=%v, got: %v\n", caseNum, tc.expFound, found)
76+
}
77+
if !tc.expFound { // idx can be random in such case
78+
continue
79+
}
80+
if idx != tc.expIdx {
81+
t.Errorf("case %d error: expecting idx=%d, got %d\n", caseNum, tc.expIdx, idx)
82+
}
83+
}
84+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// https://leetcode.com/problems/find-target-indices-after-sorting-array/
2+
package find_target_indices_after_sorting_array
3+
4+
import (
5+
"sort"
6+
)
7+
8+
func targetIndices(nums []int, target int) []int {
9+
sort.Sort(sort.IntSlice(nums))
10+
11+
// Find elements
12+
l, r := 0, len(nums)
13+
for l < r {
14+
m := (l + r) / 2
15+
if nums[m] < target {
16+
l = m + 1
17+
} else {
18+
r = m
19+
}
20+
}
21+
22+
// Collect all indices
23+
res := make([]int, 0)
24+
for ; l < len(nums) && nums[l] == target; l++ {
25+
res = append(res, l)
26+
}
27+
return res
28+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package find_target_indices_after_sorting_array
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func Test_targetIndices(t *testing.T) {
9+
cases := []struct {
10+
nums []int
11+
target int
12+
exp []int
13+
}{
14+
{
15+
nums: []int{1, 2, 5, 2, 3},
16+
target: 2,
17+
exp: []int{1, 2},
18+
},
19+
{
20+
nums: []int{1, 2, 5, 2, 3},
21+
target: 3,
22+
exp: []int{3},
23+
},
24+
{
25+
nums: []int{1, 2, 5, 2, 3},
26+
target: 5,
27+
exp: []int{4},
28+
},
29+
}
30+
31+
for idx, tc := range cases {
32+
out := targetIndices(tc.nums, tc.target)
33+
if !reflect.DeepEqual(out, tc.exp) {
34+
t.Errorf("case %d error: \n-- got: %v\n-- expected: %v", idx, out, tc.exp)
35+
}
36+
}
37+
}

0 commit comments

Comments
(0)

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