diff --git a/tools/binsearch.go b/tools/binsearch.go new file mode 100644 index 0000000..e847f32 --- /dev/null +++ b/tools/binsearch.go @@ -0,0 +1,84 @@ +package tools + +func BinarySearch(nums []int, target int) int { + left := 0 + right := len(nums) - 1 //注意 + + for left <= right { //注意 + mid := left + (right-left)/2 + if nums[mid] == target { + return mid + } else if nums[mid] < target { + left = mid + 1 //注意 + } else if nums[mid] > target { + right = mid - 1 //注意 + } + } + return -1 +} +func LeftBound(nums []int, target int) int { + if len(nums) == 0 { + return -1 + } + left := 0 + right := len(nums) //注意 + + for left < right { //注意 + mid := left + (right-left)/2 + if nums[mid] == target { + right = mid + } else if nums[mid] < target { + left = mid + 1 + } else if nums[mid] > target { + right = mid //注意 + } + } + if left == len(nums) || nums[left] != target { + return -1 + } + return left +} +func LeftBound2(nums []int, target int) int { + left := 0 + right := len(nums) - 1 //注意 + + for left <= right { //注意 + mid := left + (right-left)/2 + if nums[mid] == target { + //收缩右侧边界 + right = mid - 1 + } else if nums[mid] < target { + //搜索区间变为 [mid+1, right] + left = mid + 1 //注意 + } else if nums[mid] > target { + //搜索区间变为 [left, mid-1] + right = mid - 1 + } + } + if left >= len(nums) || nums[left] != target { + return -1 + } + return left +} +func RightBound(nums []int, target int) int { + left := 0 + right := len(nums) - 1 //注意 + + for left <= right { //注意 + mid := left + (right-left)/2 + if nums[mid] == target { + //收缩左侧边界 + left = mid + 1 + } else if nums[mid] < target { + //搜索区间变为 [mid+1, right] + left = mid + 1 //注意 + } else if nums[mid] > target { + //搜索区间变为 [left, mid-1] + right = mid - 1 + } + } + if right < 0 || nums[right] != target { + return -1 + } + return right +} diff --git a/tools/binsearch_test.go b/tools/binsearch_test.go new file mode 100644 index 0000000..1833ddd --- /dev/null +++ b/tools/binsearch_test.go @@ -0,0 +1,49 @@ +package tools + +import "testing" + +func TestBinarySearch(t *testing.T) { + myTest := struct { + Arg1 []int + Arg2 int + Want int + }{ + []int{1, 4, 7, 9, 10}, + 9, + 3, + } + res := BinarySearch(myTest.Arg1, myTest.Arg2) + if res != myTest.Want { + t.Errorf("BinarySearch(%d,%d) == %d, want %d", myTest.Arg1, myTest.Arg2, res, myTest.Want) + } +} +func TestLeftBound(t *testing.T) { + myTest := struct { + Arg1 []int + Arg2 int + Want int + }{ + []int{1, 4, 4, 4, 7, 9, 10}, + 4, + 1, + } + res := LeftBound(myTest.Arg1, myTest.Arg2) + if res != myTest.Want { + t.Errorf("LeftBound(%d,%d) == %d, want %d", myTest.Arg1, myTest.Arg2, res, myTest.Want) + } +} +func TestRightBound(t *testing.T) { + myTest := struct { + Arg1 []int + Arg2 int + Want int + }{ + []int{1, 4, 4, 4, 7, 9, 10}, + 4, + 3, + } + res := RightBound(myTest.Arg1, myTest.Arg2) + if res != myTest.Want { + t.Errorf("RightBound(%d,%d) == %d, want %d", myTest.Arg1, myTest.Arg2, res, myTest.Want) + } +} diff --git a/tools/singlelist.go b/tools/singlelist.go new file mode 100644 index 0000000..a03bd81 --- /dev/null +++ b/tools/singlelist.go @@ -0,0 +1,47 @@ +package tools + +// 单链表节点的结构 +type ListNode struct { + val int + next *ListNode +} + +func NewListNode(x int) *ListNode { + return &ListNode{ + val: x, + } +} +func ReverseList(head *ListNode) *ListNode { + if head.next == nil { + return head + } + last := ReverseList(head.next) + head.next.next = head + head.next = nil + return last +} + +var successor *ListNode // 后驱节点 +// 将链表的前 n 个节点反转(n <= 链表长度) +func ReverseListN(head *ListNode, n int) *ListNode { + if n == 1 { + // 记录第 n + 1 个节点 + successor = head.next + return head + } + // 以 head.next 为起点,需要反转前 n - 1 个节点 + last := ReverseListN(head.next, n-1) + head.next.next = head + // 让反转之后的 head 节点和后面的节点连起来 + head.next = successor + return last +} + +func ReverseBetween(head *ListNode, m int, n int) *ListNode { + if m == 1 { + return ReverseListN(head, m) + } + // 前进到反转的起点触发 base case + head.next = ReverseBetween(head.next, m-1, n-1) + return head +} diff --git a/tools/sorts_test.go b/tools/sorts_test.go index c2ed9d6..4e34f46 100644 --- a/tools/sorts_test.go +++ b/tools/sorts_test.go @@ -40,3 +40,6 @@ func TestMergeSort(t *testing.T) { MergeSort(&arr, 0, len(arr)-1) t.Log(arr) } +func TestNilChannel(t *testing.T) { + NilChannel() +} diff --git a/tools/stringutil.go b/tools/stringutil.go index 8adb42e..ae2e21f 100644 --- a/tools/stringutil.go +++ b/tools/stringutil.go @@ -88,3 +88,7 @@ func ShowStringByte(str string) { fmt.Println(i, c) } } +func NilChannel() { + var ch chan int + ch <- 1 +}