算法练习

pull/23/head
陶士涵 4 years ago
parent 5be85033f8
commit 271973dd1a

@ -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
}

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

@ -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
}

@ -40,3 +40,6 @@ func TestMergeSort(t *testing.T) {
MergeSort(&arr, 0, len(arr)-1)
t.Log(arr)
}
func TestNilChannel(t *testing.T) {
NilChannel()
}

@ -88,3 +88,7 @@ func ShowStringByte(str string) {
fmt.Println(i, c)
}
}
func NilChannel() {
var ch chan int
ch <- 1
}

Loading…
Cancel
Save