剑指offer-Golang实现

package main

import (
	"container/heap"
	"container/list"
	"math"
	"sort"
	"strconv"
	"strings"
)

func main() {

}

//03:数组中重复的数字
func findRepeatNumber(nums []int) int {
	if nums == nil {
		return -1
	}
	var tmp int
	for i := 0; i < len(nums); i++ {
		if nums[i] > len(nums) - 1 || nums[i] < 0 {
			return -1
		}
		for nums[i] != i {
			if nums[i] == nums[nums[i]] {
				return nums[i]
			}
			tmp = nums[i]
			nums[i] = nums[nums[i]]
			nums[tmp] = tmp
		}
	}
	return -1
}

//04:二维数组中的查找
func findNumberIn2DArray(matrix [][]int, target int) bool {
	if len(matrix) == 0 {
		return false
	}

	if len(matrix[0]) == 0 {
		return false
	}

	row := 0
	col := len(matrix[0]) - 1
	for row <= len(matrix) - 1 && col >= 0 {
		if matrix[row][col] < target {
			row++
		} else if matrix[row][col] > target {
			col--
		} else {
			return true
		}
	}
	return false
}

//05:替换空格
func replaceSpace(s string) string {
	str := ""
	for _, v := range s {
		if v == ' ' {
			str += "%20"
		} else {
			str += string(v)
		}
	}
	return str
}

//06: 从尾到头打印链表
//方法一:先遍历链表个数,创建等长切片,然后在切片中从尾部开始存链表头部数据
//于方法二相比,不需要频繁扩容,减少内存消耗
func reversePrint(head *ListNode) []int {
	if head == nil {
		return nil
	}
	n := 0
	cur := head
	for head != nil {
		n++
		head = head.Next
	}
	arr := make([]int, n)
	for i := n - 1; cur != nil; i-- {
		arr[i] = cur.Val
		cur = cur.Next
	}
	return arr
}
//方法二:先反转链表,再依次存入
func reversePrint(head *ListNode) []int {
	if head == nil {
		return nil
	}

	var pre *ListNode
	cur := head
	next := head
	for cur != nil {
		next = cur.Next
		cur.Next = pre
		pre = cur
		cur = next
	}
	arr := make([]int, 0)
	for pre != nil {
		arr = append(arr, pre.Val)
		pre = pre.Next
	}
	return arr
}

//09: 用两个栈实现队列
//方法一:用slice实现
type CQueue struct {
	stack1 [] int
	stack2 [] int
}


func Constructor() CQueue {
	return CQueue{}
}


func (this *CQueue) AppendTail(value int)  {
	this.stack1 = append(this.stack1, value)
}


func (this *CQueue) DeleteHead() int {
	//只有stack2中元素被pop完后才从stack1中拿
	if len(this.stack2) == 0 {
		for i := 0; i <= len(this.stack1) - 1; i++ {
			this.stack2 = append(this.stack2, this.stack1[len(this.stack1)-1-i])
		}
		this.stack1 = make([]int, 0)
	}

	if len(this.stack2) > 0 {
		result := this.stack2[len(this.stack2)-1]
		this.stack2 = this.stack2[0:len(this.stack2)-1]
		return result
	}
	return -1
}
//方法二:用list实现
type CQueue struct {
	stack1, stack2 *list.List
}


func Constructor() CQueue {
	return CQueue{
		stack1: list.New(),
		stack2: list.New(),
	}
}


func (this *CQueue) AppendTail(value int)  {
	this.stack1.PushBack(value)
}


func (this *CQueue) DeleteHead() int {
	//只有stack2中元素被pop完后才从stack1中拿
	if this.stack2.Len() == 0 {
		for this.stack1.Len() > 0 {
			this.stack2.PushBack(this.stack1.Remove(this.stack1.Back()))
		}
	}

	if this.stack2.Len() != 0 {
		e := this.stack2.Back()
		this.stack2.Remove(e)
		return e.Value.(int)
	}
	return -1
}

//10:斐波那契
//方法1:动态规划
func fib(n int) int {
	if n == 0 || n == 1 {
		return n
	}
	a := 0
	b := 1
	ret := 1
	for i := 2; i <= n; i++ {
		ret = a + b
		a = b
		b = ret
	}
	return ret % 1000000007
}
//方法2:递归
func fib(N int) int {
	f0, f1 := 0, 1
	for i := 0; i < N; i++ {
		f0,f1 = f1,(f0 + f1) % 1000000007;
	}
	return f0
}
//方法3:矩阵快速幂

//11:旋转数组的最小数字
func minArray(numbers []int) int {
	if numbers == nil {
		return -1
	}
	left := 0
	right := len(numbers) - 1
	for left < right {
		if numbers[left] < numbers[right] {
			return numbers[left]
		}
		mid := left + (right - left) / 2
		if numbers[mid] > numbers[right] {
			left = mid + 1
		} else if numbers[mid] < numbers[right] {
			right = mid
		} else {
			right--
		}
	}
	return numbers[left]
}

//12:矩阵中的路径
func exist(board [][]byte, word string) bool {
	if word == "" || board == nil {
		return false
	}

	row := len(board)
	col := len(board[0])
	visited := make([][]bool, row)
	for i := 0; i < row; i++ {
		visited[i] = make([]bool, col)
	}
	for i := 0; i < row; i++ {
		for j := 0; j < col; j++ {
			if board[i][j] == word[0] {
				if backtrack(board, word, i, j, 0, &visited) {
					return true
				}
			}
		}
	}
	return false
}

func backtrack(board [][]byte, word string, x int, y int, cunt int, visited *[][]bool) bool {
	if cunt == len(word) {
		return true
	}
	if x >= 0 && x < len(board) && y >= 0 && y < len(board[0]) && (*visited)[x][y] == false && board[x][y] == word[cunt] {
		(*visited)[x][y] = true
		if backtrack(board, word, x + 1, y, cunt+1, visited) || backtrack(board, word, x, y + 1, cunt + 1, visited) || backtrack(board, word, x - 1, y, cunt+1, visited) || backtrack(board, word, x, y - 1, cunt + 1, visited) {
			return true
		}

		(*visited)[x][y] = false
	}
	return false
}

//13:机器人的运动范围
func movingCount(m int, n int, k int) int {
	if k < 0 {
		return 0
	}
	visited := make([][]bool, m)
	for i:= 0; i < m; i++ {
		visited[i] = make([]bool, n)
	}
	return dfs(0, 0, m, n, k, &visited)

}

func dfs(x, y, m, n, k int, visited *[][]bool) int {
	if (x >= m || y >= n || k < sum(x, y) || (*visited)[x][y] == true) {
		return 0
	}
	(*visited)[x][y] = true
	return 1 + dfs(x + 1, y, m, n, k, visited) + dfs(x, y + 1, m, n, k, visited)
}

func sum (x, y int) int {
	sum := 0
	for x != 0 {
		sum += x % 10
		x /= 10
	}

	for y != 0 {
		sum += y % 10
		y /= 10
	}

	return sum
}

//14:剪绳子
// func cuttingRope(n int) int {
//     if n == 2 {
//         return 1
//     } else if n == 3 {
//         return 2
//     }

//     ret := make([]int, n+1)
//     for i := 1; i <= 4; i++ {
//         ret[i] = i
//     }
//     for i := 5; i <= n; i++ {
//         for j := 1; j < i; j++ {
//             ret[i] = max(ret[i], j * ret[i - j])
//         }
//     }
//     return ret[n]
// }

// func max(a, b int) int{
//     if a > b {
//         return a
//     }
//     return b
// }
func cuttingRope(n int) int {
	if n == 2 || n == 3 {
		return n - 1
	}
	ret := 1
	for n > 4 {
		n -= 3
		ret *= 3
	}
	return ret * n
}

//15:二进制中1的个数
func hammingWeight(num uint32) int {
	count := 0
	for num != 0 {
		count++
		num = num & (uint32(num) - 1)
	}
	return count
}

//16:数值的整数次方
func myPow(x float64, n int) float64 {
	if n < 0 {
		n = - n
		x = 1 / x
	}
	if x == 0 {
		return 0
	}

	return e_power(x, n)
}

func e_power(x float64, n int) float64 {
	if n == 0 {
		return 1
	}
	ret := e_power(x, n / 2)
	if n % 2 == 1{
		return ret * ret * x
	} else {
		return ret * ret
	}
}

//17:打印从1到最大的n位数
func printNumbers(n int) []int {
	var ret []int
	var max int
	for n > 0{
		max = max * 10 + 9
		n--
	}
	for i := 1; i <= max; i++ {
		ret = append(ret,i)
	}
	return ret
}
//考虑大数,用字符串表示

//18:删除链表的节点
//可双指针也可单指针
func deleteNode(head *ListNode, val int) *ListNode {
	if head == nil {
		return nil
	}

	if head.Val == val {
		return head.Next
	}

	cur, pre := head, head
	for cur != nil && cur.Val != val {
		pre, cur = cur, cur.Next
	}

	if cur != nil {
		pre.Next = cur.Next
	}

	return head
}

//2021/8/28
//19:正则表达式匹配
//方法一:分三种情况迭代
func isMatch(s string, p string) bool {
	if len(s) < 0 || len(p) < 0 {
		return false
	}

	sindex, pindex := 0, 0
	return matchcore(s, p, sindex, pindex)
}

func matchcore(s string, p string, sindex int, pindex int) bool {
	if sindex == len(s) && pindex == len(p) {
		return true
	}

	if sindex != len(s) && pindex == len(p) {
		return false
	}

	if pindex + 1 < len(p) && '*' == p[pindex + 1] {
		if sindex < len(s) && s[sindex] == p[pindex] || sindex < len(s) && '.' == p[pindex] {
			return matchcore(s, p, sindex + 1, pindex + 2) || //等效于匹配一次
				matchcore(s, p, sindex, pindex + 2) || //等效于匹配0次
				matchcore(s, p, sindex + 1, pindex)  //等效于匹配N次
		} else {
			return matchcore(s, p, sindex, pindex + 2)
		}
	}

	if sindex < len(s) && s[sindex] == p[pindex] || sindex < len(s) && '.' == p[pindex] {
		return matchcore(s, p, sindex + 1, pindex + 1)
	}
	return false
}
//方法二:递归
// 终止条件:p为空时,s为空返回true,s不空返回false
// first标志首位是否相等,p[0]是.也表示相等
// (1)如果p的第2位为*
//    ①首位相同 则等同于判断s[1:]和p (忽略s[0])
//    ②首位不同 则等同于判断s和p[2:] (将p前两位x*和空值配对)
// (2)否则不要期待奇迹出现了,
//    首位如果相等就各向后移一位,判断s[1:]和p[1:]
//    如果不等就是false
// 这里利用了go字符串的截断符号
func isMatch(s string, p string) bool {
	if len(p) == 0 {
		return len(s) == 0
	}
	var first bool
	if len(s) > 0 && (s[0] == p[0] || p[0] == '.') {
		first = true
	}
	if len(p) > 1 && p[1] == '*' {
		return (first && isMatch(s[1:], p)) || isMatch(s, p[2:])
	}
	return first && isMatch(s[1:], p[1:])
}

//20:表示数值的字符串
func isNumber(s string) bool {
	s = strings.Trim(s, " ")
	if len(s) > 0 && (s[0] == '+' || s[0] == '-') {
		s = s[1:]
	}

	if len(s) == 0 {
		return false
	}

	var numflag, pointflag, expflag bool
	for i := 0; i < len(s); i++ {
		if !((s[i] >= '0' && s[i] <= '9') || s[i] == '.' || s[i] == 'e' || s[i] == 'E') {
			return false
		}

		if s[i] >= '0' && s[i] <= '9' {
			numflag = true
			continue
		}

		if s[i] == 'e' || s[i] == 'E' {
			if !numflag {
				return false
			}
			if !expflag {
				expflag, pointflag = true, true
				if i + 1 == len(s) {
					return false
				}
				if s[i + 1] == '+' || s[i + 1] == '-' {
					i++
				}
				if i + 1 >= len(s) {
					return false
				}
				continue
			} else {
				return false
			}
		}

		if s[i] == '.' {
			if expflag == true {
				return false
			}
			if pointflag == false {
				pointflag = true
				continue
			} else {
				return false
			}
		}
	}

	if !numflag && pointflag {
		return false
	}

	return numflag
}

//21:调整数组顺序使得奇数位于偶数前面
//方法一:头尾指针
func exchange(nums []int) []int {
	if nums == nil {
		return nil
	}
	left, right := 0, len(nums) - 1
	for left < right {
		if nums[left] & 1 != 0 {
			left++
			continue
		}
		if nums[right] & 1 != 1 {
			right--
			continue
		}
		nums[right], nums[left] = nums[left], nums[right]
		left++
		right--
	}

	return nums
}
//方法二:快慢指针
func exchange(nums []int) []int {
	if nums == nil {
		return nil
	}
	fast, slow := 0, 0
	for fast < len(nums) {
		if nums[fast] & 1 == 1 {
			nums[slow], nums[fast] = nums[fast], nums[slow]
			slow++
		}
		fast++
	}
	return nums
}

//22:链表中倒数第k个节点
//方法一:快慢指针
func getKthFromEnd(head *ListNode, k int) *ListNode {
	if head == nil || k <= 0 {
		return nil
	}
	fast, slow := head, head
	for i := 0; i < k; i++ {
		if fast == nil {
			return nil
		}
		fast = fast.Next
	}

	for fast != nil {
		fast = fast.Next
		slow = slow.Next
	}

	return slow
}
//方法二:用切片来临时存储
func FindKthToTail1( pHead *ListNode ,  k int ) *ListNode {
    if pHead == nil || k <= 0{
        return nil
    }
    list := make([]*ListNode, 0)
    for pHead != nil {
        list = append(list, pHead)
        pHead = pHead.Next
    }
    if len(list) < k {
        return nil
    }
    return list[len(list)-k]
}

//24:反转链表
func reverseList(head *ListNode) *ListNode {
	var pre *ListNode
	next := head
	for head != nil {
		next = head.Next
		head.Next = pre
		pre = head
		head = next
	}
	return pre
}

//25:合并两个排序的链表
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
	if l1 == nil && l2 == nil {
		return nil
	}

	ret := &ListNode{Val:-1, Next:nil}
	result := ret
	for l1 != nil && l2 != nil {
		if l1.Val < l2.Val {
			ret.Next = l1
			l1 = l1.Next
			ret = ret.Next
		} else {
			ret.Next = l2
			l2 = l2.Next
			ret = ret.Next
		}
	}
	for l1 != nil {
		ret.Next = l1
		l1 = l1.Next
		ret = ret.Next
	}
	for l2 != nil {
		ret.Next = l2
		l2 = l2.Next
		ret = ret.Next
	}
	return result.Next
}

//26:树的子结构 dfs:深度优先搜索
func isSubStructure(A *TreeNode, B *TreeNode) bool {
	if A == nil || B == nil {
		return false
	}
	return issubtree(A, B) || isSubStructure(A.Right, B) || isSubStructure(A.Left, B)
}

func issubtree(a *TreeNode, b *TreeNode) bool {
	if b == nil {
		return true
	}
	if a == nil {
		return false
	}
	return a.Val == b.Val && issubtree(a.Left, b.Left) && issubtree(a.Right, b.Right)
}

//27:二叉树的镜像
func mirrorTree(root *TreeNode) *TreeNode {
	if root == nil {
		return nil
	}
	root.Right, root.Left = root.Left, root.Right
	mirrorTree(root.Right)
	mirrorTree(root.Left)
	return root
}

//28:对称的二叉树
func isSymmetric(root *TreeNode) bool {
	if root == nil {
		return true
	}

	return isSym(root.Left, root.Right)
}

func isSym (left, right *TreeNode) bool {
	if left == nil && right == nil {
		return true
	}
	if left == nil || right == nil {
		return false
	}
	if left.Val != right.Val {
		return false
	}
	return isSym(left.Left, right.Right) && isSym(left.Right, right.Left)
}

//29:顺时针打印矩阵
func spiralOrder(matrix [][]int) []int {
	if len(matrix) == 0 || len(matrix[0]) == 0 {
		return nil
	}
	col := len(matrix[0]) - 1
	row := len(matrix) - 1
	ret := make([]int, 0)
	leftx, lefty, rightx, righty := 0, 0, row, col
	for leftx <= rightx && lefty <= righty {
		for i := lefty; i <= righty; i++ {
			ret = append(ret, matrix[leftx][i])
		}
		for j := leftx + 1; j <= rightx; j++ {
			ret = append(ret, matrix[j][righty])
		}
		if leftx != rightx {
			for i := righty - 1; i >= lefty; i-- {
				ret = append(ret, matrix[rightx][i])
			}
		}
		if lefty != righty {
			for j := rightx - 1; j > leftx; j-- {
				ret = append(ret, matrix[j][lefty])
			}
		}
		leftx++
		lefty++
		rightx--
		righty--
	}
	return ret
}

//30:包含min的栈
type MinStack struct {
	stack []int
}


/** initialize your data structure here. */
func Constructor() MinStack {
	return MinStack{}
}


func (this *MinStack) Push(x int)  {
	this.stack = append(this.stack, x)
}


func (this *MinStack) Pop()  {
	if len(this.stack) > 0 {
		this.stack = this.stack[0:len(this.stack)-1]
	}
}


func (this *MinStack) Top() int {
	result := -1
	if len(this.stack) > 0 {
		result = this.stack[len(this.stack)-1]
	}
	return result
}


func (this *MinStack) Min() int {
	min := -1
	if len(this.stack) > 0 {
		min = this.stack[0]
	}

	for _, v := range this.stack {
		if min > v {
			min = v
		}
	}
	return min
}

//31:栈的压入、弹出序列
func validateStackSequences(pushed []int, popped []int) bool {
	if pushed == nil || popped == nil {
		return false
	}
	tmp := make([]int, 0)
	for _, v := range popped {
		//弹出序列中不等于辅助栈尾时,将压入序列压入辅助栈
		for len(tmp) == 0 || tmp[len(tmp)-1] != v {
			if len(pushed) == 0 {
				return false
			}
			tmp = append(tmp, pushed[0])
			pushed = pushed[1:]
		}
		//弹出栈尾
		tmp = tmp[0:len(tmp)-1]
	}
	return true
}

//32:从上往下打印二叉树
func levelOrder(root *TreeNode) []int {
	if root == nil {
		return nil
	}

	tmp := make([]*TreeNode, 0)
	ret := make([]int, 0)
	tmp = append(tmp, root)
	currentlast := root
	var nextlast *TreeNode
	for len(tmp) > 0 {
		removed := tmp[0]
		tmp = tmp[1:]
		ret = append(ret, removed.Val)
		if removed.Left != nil {
			tmp = append(tmp, removed.Left)
			nextlast = removed.Left
		}
		if removed.Right != nil {
			tmp = append(tmp, removed.Right)
			nextlast = removed.Right
		}
		if removed == currentlast {
			currentlast = nextlast
		}
	}
	return ret
}

//33:二叉搜索树的后序遍历序列
func verifyPostorder(postorder []int) bool {
	length := len(postorder)
	if length == 0 {
		return true
	}
	return check(postorder, 0, length - 1)
}

//看到遍历序列就要想到用两个index
func check(postorder []int, l, r int) bool {
	if l >= r {
		return true
	}
	root := postorder[r]
	rightroot := r - 1
	//rightroot是左子树的最后一个数
	for rightroot >= 0 && postorder[rightroot] > root {
		rightroot--
	}
	for leftroot := l; leftroot <= rightroot; leftroot++ {
		//左子树的每一个数都要小于根的值
		if postorder[leftroot] > root {
			return false
		}
	}
	return check(postorder,l, rightroot) && check(postorder, rightroot + 1, r - 1)
}

//34:二叉树中和为某一值的路径
func pathSum(root *TreeNode, target int) [][]int {
	if root == nil {
		return nil
	}
	ans := make([]int, 0)
	ret := make([][]int, 0)
	dfs1(root, target, ans, &ret)
	return ret
}

func dfs1(root *TreeNode, sum int, ans []int, ret *[][]int) {
	if root == nil{
		return
	}
	ans = append(ans, root.Val)
	if sum == root.Val && root.Right == nil && root.Left == nil {
		//*ret = append(*ret, ans)
		//slice是一个指向底层的数组的指针结构体
		//因为是先序遍历,如果 root.Right != nil ,arr 切片底层的数组会被修改
		//所以这里需要 copy arr 到 tmp,再添加进 ret,防止 arr 底层数据修改带来的错误
		tmp := make([]int,len(ans))
		copy(tmp,ans)
		*ret = append(*ret,tmp)
	}
	dfs1(root.Left, sum-root.Val, ans, ret)
	dfs1(root.Right, sum-root.Val, ans, ret)
	ans = ans[:len(ans) - 1]
}

//35:复杂链表的复制
func copyRandomList(head *Node) *Node {
	if head == nil {
		return nil
	}
	tmp := head
	for tmp != nil {
		next := tmp.Next
		// clone := new(Node)
		// tmp.Next = clone
		// clone.Next = next

		//必须要赋值,否则new出来的val=0
		copyNode := &Node{
			Val: tmp.Val,
			Next: nil,
			Random: nil,
		}

		tmp.Next = copyNode
		copyNode.Next = next
		tmp = next
	}

	tmp = head
	for tmp != nil {
		if tmp.Random != nil {
			tmp.Next.Random = tmp.Random.Next
		} else {
			tmp.Next.Random = nil
		}
		tmp = tmp.Next.Next
	}

	tmp = head
	clonehead := tmp.Next
	for tmp != nil {
		clone := tmp.Next
		tmp.Next = clone.Next
		if clone.Next != nil {
			clone.Next = clone.Next.Next
		}
		tmp = tmp.Next
	}
	return clonehead
}

//~37:序列化二叉树
func Serialize( root *TreeNode ) string {
	if root == nil {
		return "[]"
	}
	ret := make([]string, 0)

	rootlist := make([]*TreeNode, 1)
	rootlist[0] = root
	for len(rootlist) != 0 {
		removed := rootlist[0]
		rootlist = rootlist[1:]
		if removed != nil {
			ret = append(ret, strconv.Itoa(removed.Val))
			rootlist = append(rootlist, removed.Left)
			rootlist = append(rootlist, removed.Right)
		} else {
			ret = append(ret, "#")
		}
	}
	return "["+strings.Join(ret,",")+"]"
}

func Deserialize( s string ) *TreeNode {
	s = s[1:len(s) - 1]
	if s == "" {
		return nil
	}
	strs, i := strings.Split(s, ","), 1
	root := &TreeNode{}
	root.Val, _ = strconv.Atoi(strs[0])
	rootlist := make([]*TreeNode, 1)
	rootlist[0] = root
	for len(rootlist) > 0 {
		removed := rootlist[0]
		rootlist = rootlist[1:]
		if strs[i] != "#" {
			removed.Left = &TreeNode{}
			removed.Left.Val, _ = strconv.Atoi(strs[i])
			rootlist = append(rootlist, removed.Left)
		}
		i++
		if strs[i] != "#" {
			removed.Right = &TreeNode{}
			removed.Right.Val, _ = strconv.Atoi(strs[i])
			rootlist = append(rootlist, removed.Right)
		}
		i++
	}
	return root
}

//38:字符串的排列
func permutation(s string) []string {
	pos := 0
	ori := []byte(s)
	result := []string{}
	StringSort(pos, ori, &result)
	// sort.Slice(result, func(i, j int) bool {
	//     return result[i] < result[j]
	// })
	return result
}

func StringSort(x int, bytes []byte, res *[]string) {
	if x + 1 == len(bytes) {
		*res = append(*res, string(bytes))
	}
	//每一层迭代分别记录自己的flag
	flag := make(map[byte]bool)
	for i := x; i < len(bytes); i++ {
		if !flag[bytes[i]] {
			bytes[x], bytes[i] = bytes[i], bytes[x]
			flag[bytes[x]] = true
			//把当前层的后面字母一个一个换到数组首位继续迭代
			StringSort(x+1, bytes, res)
			bytes[x], bytes[i] = bytes[i], bytes[x]
		}
	}
}

//40:最小K个数
func getLeastNumbers(arr []int, k int) []int {
	if k == 0 || arr == nil {
		return nil
	}

	sort.Ints(arr)
	if len(arr) == k {
		return arr
	}
	window := make([]int, 0)
	for j := 0; j < k; j++ {
		window = append(window, arr[j])
	}
	return window
}

//41:数据流中的中位数
//小跟堆大根堆分别储存
type MedianFinder struct {
	maxH *maxHeap
	minH *minHeap
}


/** initialize your data structure here. */
func Constructor() MedianFinder {
	maxH:=&maxHeap{}
	minH:=&minHeap{}
	heap.Init(maxH)
	heap.Init(minH)
	return MedianFinder{maxH,minH}
}


func (this *MedianFinder) AddNum(num int)  {
	//
	if this.maxH.Len()==0 {
		heap.Push(this.minH,num)
	}else {
		maxHPeek:=this.maxH.Peek()

		if num>=maxHPeek {
			heap.Push(this.minH,num)
		}else {
			heap.Push(this.maxH,num)
		}
	}
	// fmt.Println("高度变化前",this.minH,this.maxH)


	//看高度差是否超过2,超过2就平衡下
	if this.minH.Len()-this.maxH.Len()>=2 {
		temp:=heap.Pop(this.minH)
		heap.Push(this.maxH,temp)
	}

	if this.minH.Len()-this.maxH.Len()<=-2 {
		temp:=heap.Pop(this.maxH)
		heap.Push(this.minH,temp)
	}
	// fmt.Println("高度变化后",this.minH,this.maxH)
}


func (this *MedianFinder) FindMedian() float64 {
	//高度不相等,多的那个堆顶就是中位数
	if this.minH.Len()>this.maxH.Len() {
		return float64(this.minH.Peek())
	}else if this.minH.Len()<this.maxH.Len() {
		return float64(this.maxH.Peek())
	}
	//高度相等,中位数是两个堆顶取出除二
	return (float64(this.minH.Peek())+float64(this.maxH.Peek()))/2
}


/**
 * Your MedianFinder object will be instantiated and called as such:
 * obj := Constructor();
 * obj.AddNum(num);
 * param_2 := obj.FindMedian();
 */

type maxHeap []int

func (h *maxHeap) Len() int {
	return len(*h)
}

func (h *maxHeap) Less(i, j int) bool {
	return (*h)[i] > (*h)[j]
}

func (h *maxHeap) Swap(i, j int) {
	(*h)[i], (*h)[j] = (*h)[j], (*h)[i]
}

func (h *maxHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}

func (h *maxHeap) Pop() (v interface{}) {
	*h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1]
	return
}

// 查看堆顶元素
func (h *maxHeap) Peek() int {
	return (*h)[0]
}

type minHeap []int

func (h *minHeap) Len() int {
	return len(*h)
}

func (h *minHeap) Less(i, j int) bool {
	return (*h)[i] < (*h)[j]
}

func (h *minHeap) Swap(i, j int) {
	(*h)[i], (*h)[j] = (*h)[j], (*h)[i]
}

func (h *minHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}

func (h *minHeap) Pop() (v interface{}) {
	*h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1]
	return
}

// 查看堆顶元素
func (h *minHeap) Peek() int {
	return (*h)[0]
}

//42:连续子数组的最大和
func maxSubArray(nums []int) int {
	max := nums[0]
	for i := 1; i < len(nums); i++ {
		if nums[i] + nums[i - 1] > nums[i] {
			nums[i] += nums[i-1]
		}
		if nums[i] > max {
			max = nums[i]
		}
	}
	return max
}

//43:1~n 整数中 1 出现的次数
func countDigitOne(n int) int {
	if n <= 0 {
		return 0
	}

	ns := strconv.Itoa(n)
	return count(ns)
}

func count(n string) int {
	if len(n) == 0 {
		return 0
	}

	if len(n) == 1 && n[0] == '0' {
		return 0
	}

	if len(n) == 1 && n[0] > '0' {
		return 1
	}
	first1 := 0
	if n[0] == '1' {
		res, _ := strconv.Atoi(n[1:])
		first1 = res + 1
	} else if n[0] > '1' {
		first1 = int(math.Pow(10, float64(len(n[1:]))))
	}
	other := int(n[0] - '0') * int(math.Pow(10,float64(len(n[1:])-1))) * len(n[1:])

	return first1 + other + count(n[1:])
}

//44:数字序列中某一位的数字
func findNthDigit(n int) int {
	start, digit, numbers := 1, 1, 9
	for n - numbers > 0 {
		n -= numbers
		start *= 10
		digit += 1
		numbers = 9 * start * digit
	}
	num := start + (n - 1) / digit
	s := strconv.Itoa(num)
	res := int(s[(n - 1) % digit]-'0')
	return res
}

//45:把数组排成最小的数
func minNumber(nums []int) string {
	length := len(nums)
	if length == 0 {
		return ""
	}
	data := []string{}
	for _, n := range nums {
		data = append(data, strconv.Itoa(n))
	}
	sort.Slice(data, func (i, j int) bool {
		return data[i] + data[j] < data[j] + data[i]
	})
	result := ""
	for _, n := range data {
		result += n
	}
	return result
}

//46:把数字翻译成字符串
func translateNum(num int) int {
	str := strconv.Itoa(num)
	//p为f(i-2),q为f(i-1),拆成两部分,q即代表i位自己单独翻译时的那一次
	p, q, r := 0, 0, 1
	for i := 0; i < len(str); i++ {
		p, q, r = q, r, 0
		r += q
		if i == 0 {
			continue
		}
		if str[i-1:i+1] >= "10" && str[i-1:i+1] <= "25" {
			r += p
		}
	}
	return r
}

//47:礼物的最大价值
func maxValue(grid [][]int) int {
	row := len(grid)
	col := len(grid[0])
	//开辟多一行一列的空间,避免i=0||j=0时的判断
	dp := make([][]int, row+1)
	for i := 0; i < len(dp); i++ {
		dp[i] = make([]int, col+1)
	}
	for i := 1; i < len(dp); i++ {
		for j := 1; j < len(dp[0]); j++ {
			dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + grid[i-1][j-1]
		}
	}
	return dp[row][col]
}

//48:最长不含重复字符的子字符串
func lengthOfLongestSubstring(s string) int {
	if len(s) == 0 {
		return 0
	}

	set := make(map[byte]bool)

	left := 0
	set[s[0]] = true
	maxLen := 1
	for right := 1; right < len(s); {
		b := set[s[right]]
		if !b {
			set[s[right]] = true
			right++
		} else {
			//一直从左向右删除,知道将当前的字母第一次出现的位置删掉
			delete(set, s[left])
			left++
		}
		if right - left > maxLen {
			maxLen =  right - left
		}
	}
	return maxLen
}

//49:丑数
func nthUglyNumber(n int) int {
	if n == 1 {
		return 1
	}
	if n == 0 {
		return 0
	}
	ret := make([]int, n)
	ret[0] = 1
	index2, index3, index5 := 0, 0, 0
	for i := 1; i < n; i++ {
		m := ret[index2] * 2
		if t := ret[index3] * 3; m > t {
			m = t
		}
		if t := ret[index5] * 5; m > t {
			m = t
		}
		ret[i] = m
		if m == ret[index2] * 2 {
			index2++
		}
		if m == ret[index3] * 3 {
			index3++
		}
		if m == ret[index5] * 5 {
			index5++
		}
	}
	return ret[n-1]
}

//50:第一个只出现一次的字符
func firstUniqChar(s string) byte {
	if len(s) <= 0 {
		return ' '
	}
	list := make([]int,26)
	length := len(s)
	for i:=0;i<length;i++ {
		list[s[i]-'a']++
	}
	for i:=0;i<length;i++{
		if list[s[i]-'a'] == 1 {
			return s[i]
		}
	}
	return ' '
}

//51:数组中的逆序对
// func reversePairs(nums []int) int {
//     return mergeSort(nums, 0, len(nums)-1)
// }

// func mergeSort(nums []int, start, end int) int {
//     if start >= end {
//         return 0
//     }
//     mid := start + (end - start)/2
//     cnt := mergeSort(nums, start, mid) + mergeSort(nums, mid + 1, end)
//     tmp := []int{}
//     i, j := start, mid + 1
//     for i <= mid && j <= end {
//         if nums[i] <= nums[j] {
//             tmp = append(tmp, nums[i])
//              左子数组当前的数与右子数组的标记位之前的数构成逆序对
//             cnt += j - (mid + 1)
//             i++
//         } else {
//             tmp = append(tmp, nums[j])
//             j++
//         }
//     }
//      左子数组剩一个,代表与右子数组中的数每一个都构成逆序对
//     for ; i <= mid; i++ {
//         tmp = append(tmp, nums[i])
//         cnt += end - (mid + 1) + 1
//     }
//     for ; j <= end; j++ {
//         tmp = append(tmp, nums[j])
//     }
//      将排序后的子数组更新到原数组中
//     for i := start; i <= end; i++ {
//         nums[i] = tmp[i - start]
//     }
//     return cnt
// }

//52:两个链表的第一个公共节点
func getIntersectionNode(headA, headB *ListNode) *ListNode {
	if headA == nil || headB == nil {
		return nil
	}
	A := headA
	B := headB
	for headA != headB {
		if headA != nil {
			headA = headA.Next
		} else {
			headA = B
		}
		if headB != nil {
			headB = headB.Next
		} else {
			headB = A
		}
	}
	return headA
}

//53:在排序数组中查找数字
func search(nums []int, target int) int {
	len := len(nums)
	number, leftbound, rightbound := 0, 0, len - 1
	if nums != nil && target >= 0 {
		for leftbound <= rightbound {
			index := (leftbound + rightbound) / 2
			if nums[index] == target {
				//判断是不是第一个K
				if index > 0 && nums[index - 1] != target || index == 0 {
					leftbound = index
					break
				} else {
					//前面还有K则将右边界设为index-1
					rightbound = index - 1
				}
			} else if nums[index] < target {
				leftbound = index + 1
			} else {
				rightbound = index - 1
			}
		}

		number = leftbound
		//直接将leftbound用来求lastTarget
		//leftbound, rightbound = 0, len - 1
		rightbound = len - 1
		for leftbound <= rightbound {
			index := (leftbound + rightbound) / 2
			if nums[index] == target {
				if index < len - 1 && nums[index + 1] != target || index == len - 1 {
					rightbound = index
					break
				} else {
					leftbound = index + 1
				}
			} else if nums[index] < target {
				leftbound = index + 1
			} else {
				rightbound = index - 1
			}
		}
		number = rightbound - number + 1
	}
	return number
}

//54:0~n-1中缺失的数字
func missingNumber(nums []int) int {
	i := len(nums)
	if i == 1{
		if nums[0] == 1 {
			return 0
		} else {
			return 1
		}
	}
	if nums[i-1] == i-1 {
		return i
	}
	l, r := 0, i - 1
	for l <= r {
		mid := l + (r - l) / 2
		if nums[mid] == mid + 1 {
			if mid == 0 {
				return 0
			} else if nums[mid - 1] == mid - 1 {
				return mid
			} else {
				r = mid - 1
			}
		} else if nums[mid] == mid {
			l = mid + 1
		}
	}
	return -1
}
//func missingNumber(nums []int) int {
//	N := len(nums)
//	l, r := 0, N-1
//	for l <= r {
//		mid := (r-l)/2 + l
//		if nums[mid] == mid {
//			l = mid+1
//		} else {
//			r = mid-1
//		}
//	}
//	return l
//}

//55:二叉搜索树的第k大节点
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func kthLargest(root *TreeNode, k int) int {
	nums := make([]int, 0)
	inorder(root, &nums)
	return nums[len(nums)-k]
}

func inorder(root *TreeNode, nums *[]int) {
	if root == nil {
		return
	}
	inorder(root.Left, nums)
	*nums = append(*nums, root.Val)
	inorder(root.Right, nums)
	return
}

//55:1.二叉树的深度
//先序遍历
// func maxDepth(root *TreeNode) int {
//     if root == nil {
//         return 0
//     }
//     return max(maxDepth(root.Left), maxDepth(root.Right)) + 1
// }

// func max(i, j int) int {
//     if i > j {
//         return i
//     }
//     return j
// }

//层序遍历
func maxDepth(root *TreeNode) int {
	if root == nil {
		return 0
	}
	rootlist := make([]*TreeNode, 0)
	rootlist = append(rootlist, root)
	count := 0
	currentlast := root
	var last *TreeNode
	for len(rootlist) > 0 {
		removed := rootlist[0]
		rootlist = rootlist[1:]
		if removed.Left != nil {
			rootlist = append(rootlist, removed.Left)
			last = removed.Left
		}
		if removed.Right != nil {
			rootlist = append(rootlist, removed.Right)
			last = removed.Right
		}
		if currentlast == removed {
			count++
			currentlast = last
		}
	}
	return count
}

func maxDepth(root *TreeNode) int {
	// 边界
	if root == nil {
		return 0
	}
	depth := 0
	var queue []*TreeNode
	queue = append(queue, root)
	// bfs
	for len(queue) > 0 {
		length := len(queue)
		for i := 0; i < length; i++ {
			//这里已经将当前层的去除掉了
			cur := queue[0]
			queue = queue[1:]
			if cur.Left != nil {
				queue = append(queue, cur.Left)
			}
			if cur.Right != nil {
				queue = append(queue, cur.Right)
			}
		}
		depth += 1
	}
	return depth
}

//55:2.平衡二叉树
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
//自上向下
// func isBalanced(root *TreeNode) bool {
//     if root == nil {
//         return true
//     }
//     return abs(maxDepth(root.Left) - maxDepth(root.Right)) <= 1 && isBalanced(root.Left) && isBalanced(root.Right)
// }

// func maxDepth(root *TreeNode) int {
//     if root == nil {
//         return 0
//     }
//     return max(maxDepth(root.Left), maxDepth(root.Right)) + 1
// }

//自下而上
func isBalanced(root *TreeNode) bool {
	return height(root) >= 0
}

func height(root *TreeNode) int {
	if root == nil {
		return 0
	}
	lh := height(root.Left)
	rh := height(root.Right)
	if lh == -1 || rh == -1 || abs(lh - rh) > 1 {
		return -1
	}
	return max(lh, rh) + 1
}

func abs(i int) int {
	if i >= 0 {
		return i
	}
	return -i
}

func max(i, j int) int {
	if i>j {
		return i
	}
	return j
}

//56:1.数组中数字出现的次数
func singleNumbers(nums []int) []int {
	a := 0
	for _, v := range nums {
		a ^= v
	}
	//此时a为两个只出现一次的数字的异或结果
	//结果中找到最低一位1的位置
	mask := a&(-a)
	// var b int
	// for b&a == 0 {
	//     b << = 1
	// }
	ret := make([]int, 2)
	for _, v := range nums {
		//使得第x位为1的数在一组,第四位为0的数在另一组。
		if v&mask == 0 {
			//一组中重复的被抵消,只剩下只出现一次的
			ret[0] ^= v
		} else {
			ret[1] ^= v
		}
	}
	return ret
}

//56:2.数组中其他数字出现3次
func singleNumber(nums []int) int {
	res:=0
	for i:=0;i<32;i++{
		count:=0
		bit:=1<<i
		for _,num:=range nums{
			if num&bit!=0{
				count++
			}
		}
		if count%3!=0{
			res|=bit
		}
	}
	return res
}

//57:1.和为s的两个数字
func twoSum(nums []int, target int) []int {
	if nums==nil || len(nums)<2 {
		return nil
	}
	left, right := 0, len(nums)-1
	//大于目标值的数字全都排除
	for nums[right]>target{
		right--
	}
	for left<right{
		if nums[left]+nums[right]==target{
			return []int{nums[left],nums[right]}
		}
		if nums[left]>target-nums[right]{
			right--
		}else{
			left++
		}
	}
	return nil
}

//57:2.和为s的连续正数序列
func findContinuousSequence(target int) [][]int {
	if target <= 2 {
		return nil
	}
	ret := make([][]int, 0)
	win := make([]int, 0)
	sum := 0
	//+2是因为当target=9时,把5append进去的时候,i=6,此时不会去消掉win前面的数
	for i := 1; i <= target/2+2; {
		if sum < target {
			win = append(win, i)
			sum += i
			i++
		} else if sum > target {
			sum -= win[0]
			win = win[1:]
		} else {
			ret = append(ret, win)
			sum -= win[0]
			win = win[1:]
		}
	}
	return ret
}

// func findContinuousSequence(target int)(res [][]int) {
// 	i,j,sum:=1,2,3

// 	for i<=target/2{
// 		if target>sum{
// 			j++
// 			sum+=j
// 		}else{
//             if target==sum {
//                  tmp:=make([]int,j-i+1)
// 			        for k:=i;k<=j;k++ {
// 				        tmp[k-i]=k
// 			        }
// 			        res=append(res,tmp)
//             }
// 			sum-=i
// 			i++
// 		}
// 	}
// 	return
// }

//58:1.翻转单词顺序
func reverseWords(s string) string {
	strList := strings.Split(s," ")
	var res []string
	for i :=len(strList)-1;i>=0;i--{
		str := strings.TrimSpace(strList[i])
		if  len(str)>0 {
			res = append(res,strList[i])
		}
	}
	return strings.Join(res," ")
}

//58:2.左旋字符串
func reverseLeftWords(s string, n int) string {
	sbyte := []byte(s)
	tmp := sbyte[0:n]
	sbyte = sbyte[n:]
	sbyte = append(sbyte, tmp...)
	return string(sbyte)
}

//59:1.滑动窗口的最大值
func maxSlidingWindow(nums []int, k int) []int {
	if k == 1 {
		return nums
	}
	ret := make([]int, 0)
	max := []int{0}
	for i := 0; i < len(nums); i++ {
		//当max的长度等于k,或者max[0]与i的距离大于k时,截断max
		if len(max) == k || i - max[0] >= k && len(max) > 1 {
			max = max[1:]
		}
		//当nums[i]大于max中的最大值时,max后面存的值也没有存在的必要
		if nums[i] >= nums[max[0]] {
			max[0] = i
			max = max[0:1]
		}
		//去除max中小于nums[i]的值,将坐标记录在比nums[i]大的数的后面
		if nums[i] < nums[max[0]] {
			for j := 1; j < len(max); j++ {
				if nums[i] > nums[max[j]] {
					max = max[0:j]
				}
			}
			max = append(max, i)
		}
		//达到滑动窗口值的大小时,每一次循环添加一个结果
		if i >= k - 1 {
			ret = append(ret, nums[max[0]])
		}
	}
	return ret
}

//59:2.队列的最大值
type MaxQueue struct {
	max []int
	queue []int
}


func Constructor() MaxQueue {
	return MaxQueue{}
}


func (this *MaxQueue) Max_value() int {
	if len(this.max) == 0 {
		return -1
	}
	return this.max[0]
}


func (this *MaxQueue) Push_back(value int)  {
	this.queue = append(this.queue, value)
	for len(this.max) > 0 && value > this.max[len(this.max) - 1] {
		this.max = this.max[:len(this.max)-1]
	}
	this.max = append(this.max, value)
}


func (this *MaxQueue) Pop_front() int {
	if len(this.queue) == 0 {
		return -1
	}
	if this.max[0] == this.queue[0] {
		this.max = this.max[1:]
	}
	value := this.queue[0]
	this.queue = this.queue[1:]
	return value
}

//60:n个色子的点数
func dicesProbability(n int) []float64 {
	if n <= 0 {
		return []float64{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}
	}
	dp := []float64{1.0/6.0, 1.0/6.0, 1.0/6.0, 1.0/6.0, 1.0/6.0, 1.0/6.0}
	for i := 2; i <= n; i++ {
		//注意是5*i,n个色子掷出的点数的可能性为6n-n+1(不可能有小于n的出现)
		tmp := make([]float64, 5*i+1)
		for j := 0; j < len(dp); j++ {
			for k := 0; k < 6; k++ {
				//这一次掷出的数字的概率为1/6
				tmp[j+k] += dp[j] / 6.0
			}
		}
		dp = tmp
	}
	return dp
}

//61:扑克牌中的顺子
func isStraight(nums []int) bool {
	if len(nums) != 5 {
		return false
	}
	sort.Ints(nums)
	index := 0
	for i := 0; i < 4; i++ {
		if nums[i] == nums[i + 1] && nums[i] != 0 {
			return false
		}
		//将index置为第一个非零的数
		if nums[i] != 0 && index == 0 {
			index = nums[i]
		}
	}
	//等于填好了0
	if nums[4] - index < 5 {
		return true
	}
	return false
}

//62:约瑟夫环
func lastRemaining(n int, m int) int {
	if n <= 0 {
		return -1
	}
	index := 0
	for i := 2; i <= n; i++ {
		index = (index+m)%i
	}
	return index
}

//63:股票最大利润
func maxProfit(prices []int) int {
	if len(prices) <= 0 {
		return 0
	}
	min := prices[0]
	maxpro := 0
	for i := 1; i < len(prices); i++ {
		if prices[i] < min {
			min = prices[i]
		} else if prices[i] - min > maxpro {
			maxpro = prices[i] - min
		}
	}
	return maxpro
}

//64:1+..+n求和
func sumNums(n int) int {
	sum := 0
	var get_sum func (num int) bool
	get_sum = func (num int) bool{
		sum += num
		//num>0相当于for的判断
		return num > 0 && get_sum(num - 1)
	}
	get_sum(n)
	return sum
}

//65:不用加减乘除做加法
func add(a int, b int) int {
	//先加一次不进位的,再跟进位加一次
	for b != 0 {
		c := (a & b) << 1 //进位和
		a ^= b //非进位和
		b = c
	}
	return a
}

//66:构建乘积数组
func constructArr(a []int) []int {
	b := make([]int,len(a))
	lastSum := 1
	for i:=0;i<len(a);i++{
		if i == 0{
			b[i] = 1
		}else{
			lastSum = lastSum*a[i-1]
			b[i] = lastSum
		}
	}

	for i:=len(a);i>0;i--{
		if i == len(a){
			lastSum = 1
		}else{
			//倒数第二个乘a的最后一个i=len(a)-1
			lastSum = lastSum * a[i]
		}
		b[i-1] *= lastSum
	}
	return b
}

//67:把字符串转换成整数
func strToInt(str string) int {
	str = strings.TrimSpace(str)
	result := 0
	sign := 1

	for i, v := range str {
		if v >= '0' && v <= '9' {
			result = result*10 + int(v-'0')
		} else if v == '-' && i == 0 {
			sign = -1
		} else if v == '+' && i == 0 {
			sign = 1
		} else {
			break
		}

		if result > math.MaxInt32 {
			if sign == -1 {
				return math.MinInt32
			}
			return math.MaxInt32
		}
	}

	return sign * result
}

//68:1.二叉搜索树的最近公共祖先
//class Solution {
//public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//while(root != null) {
//if(root.val < p.val && root.val < q.val) // p,q 都在 root 的右子树中
//root = root.right; // 遍历至右子节点
//else if(root.val > p.val && root.val > q.val) // p,q 都在 root 的左子树中
//root = root.left; // 遍历至左子节点
//else break;
//}
//return root;
//}
//}

//68:2.二叉树的最近公共祖先
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
	if root == nil || root == p || root == q {
		return root
	}
	left := lowestCommonAncestor(root.Left, p, q)
	right := lowestCommonAncestor(root.Right, p, q)
	if right == nil {
		return left
	}
	if left == nil {
		return right
	}
	return root
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值