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
}
剑指offer-Golang实现
最新推荐文章于 2021-09-12 15:42:53 发布