算法题

作者: voidFan | 来源:发表于2021-04-12 21:47 被阅读0次

    行列都是有序的二维数组,查找k是否存在【查找法】

    package main
    
    import "fmt"
    
    func Find(target int, arr [][]int) bool {
        if arr == nil || len(arr) <= 0 {
            return false
        }
    
        row := len(arr)
        cols := len(arr[0])
    
        i := row - 1      // 从左下角的元素开始查找, 也可以从右上角开始找
        j := 0
        for i >= 0 && j < cols {
            if arr[i][j] == target {
                return true
            } else if arr[i][j] > target {
                i--     // 只能往上查找
            } else {
                j++     // 只能往右查找
            }
        }
        return false
    }
    
    func main() {
        var arr = [][]int{[]int{1,2,3,4,5}, []int{6,7,8,9,10}, []int{11,12,13,15,16}, []int{17,19,20,21,22}}
        fmt.Println(Find(18, arr))
    }
    

    二维数组中的查找(行列分别有序数组的二分查找)【递归法】

    package main
    import "fmt"
    
    var arr [][]int = [][]int{[]int{1,2,8,9}, []int{2,4,9,12}, []int{4,7,10,13}, []int{6,8,11,15}}
    const N = 4
    
    func main() {
        if(BinarySearchMat(arr,0,0,4,4,9)) {
            fmt.Println(true)
        } else {
            fmt.Println(false)
        }
        return 
    }
     
    func BinarySearchMat(mat [][]int, beginR int, beginC int, sumR int, sumC int,  val int) bool {
        if (sumC <= 0 || sumR <=0) {
            return false  
        }
        halfR := sumR / 2
        halfC := sumC / 2  
        midR := beginR + halfR  
        midC := beginC + halfC  
        if (val == mat[midR][midC]) {
            return true  
        }
        if(val < mat[midR][midC]) {
            if(BinarySearchMat(mat,beginR,beginC,halfR,sumC,val)){
                return true 
            }
            if (BinarySearchMat(mat,midR,beginC,sumR - halfR ,halfC ,val)) {
                return true 
            }
        } else {// val > mat[midR][midC]
            if(BinarySearchMat(mat,midR + 1,beginC,sumR - halfR - 1,sumC,val)) {
                return true 
            }
            if (BinarySearchMat(mat,beginR,midC + 1,halfR + 1,sumC - halfC - 1,val)) {
                return true 
            }
        }
        return false  
    }
    
    

    快速排序递归实现

    package main
    //快速排序递归实现
    func QuickSort(arr []int) {
        _quicksort(arr, 0, len(arr) - 1)
    }
    
    func _quicksort(arr []int, left, right int) {
        if left < right    {
            p := partition(arr, left, right)
            _quicksort(arr, left, p - 1)
            _quicksort(arr, p + 1, right)
        }
    }
    
    func partition(arr []int, left, right int) int {
        pivot := left
        //TODO:从第二个数据开始处理:"待处理的元素"
        index := pivot + 1
        //TODO:i为遍历记数,index记录待遍历的第一个元素。遍历待遍历的数 与 参考值比较
        for i := index; i <= right; i++ {
            if arr[i] < arr[pivot] {
                arr[i], arr[index] = arr[index], arr[i] //TODO:将小于pivot的数,放在index的位置,后面依次放
                index++
            }
        }
        arr[pivot], arr[index - 1] = arr[index -1], arr[pivot]  // TODO:最后将pivot上的元素移动到合适的位置
        return index - 1
    }
    

    快速排序非递归实现

    //快速排序非递归实现
    package main
    func _quicksortOpt(arr []int, left, right int) {
        //递归退出条件
        if left >= right { return }
        pivot := arr[right] //从右边开始遍历
        i := left
        j := right - 1
        for i < j {
            for i < j && arr[i] < pivot {i++} //从左边找一个小于 p 的数
            for i < j && arr[j] > pivot {j--} //从右边找一个大于 p 的数
            arr[i], arr[j] = arr[j], arr[i]
        }
        if arr[i] >= pivot {
            arr[i], arr[right] = arr[right],arr[i]
        } else {
            i++
        }
        _quicksort(arr, left, i-1)
        _quicksort(arr, i+1, right)
    }
    
    func QuickSortOpt(arr []int) {
        _quicksortOpt(arr, 0, len(arr) - 1)
    }
    

    归并排序递归实现

    package main
    func MergeSort(arr []int) []int {
        if len(arr) <= 1 {
            return arr
        }
        //拆分数组,再合并。拆分到数组只有一个元素。
        mid := len(arr) / 2
        left := MergeSort(arr[:mid])
        right := MergeSort(arr[mid:])
    
        return Merge(left, right)
    }
    
    func Merge(left, right []int) []int {
        result := make([]int, 0)
        i, j := 0, 0  // left和right的index位置
        lLen, rLen := len(left), len(right)
        //左右两边数组,只要有长度大于0的就需要处理
        for i < lLen && j < rLen {
            if left[i] > right[j] {
                result = append(result, right[j])
                j++
                continue
            }
            result = append(result, left[i])
            i++
        }
        result = append(result, right[j:]...)
        result = append(result, left[i:]...)
        return result
    }
    

    链表排序leetcode归并解决

    func sortList(head *ListNode) *ListNode {
        // 如果 head为空或者head就一位,直接返回
        if head == nil || head.Next == nil {
            return head
        }
        // 定义快慢俩指针,当快指针到末尾的时候,慢指针肯定在链表中间位置
        slow,fast := head,head
        for fast != nil && fast.Next != nil && fast.Next.Next != nil {
            slow,fast = slow.Next,fast.Next.Next
        }
        // 把链表拆分成两段,所以设置中间位置即慢指针的next为nil
        n := slow.Next
        slow.Next = nil
        // 递归排序
        return merge(sortList(head),sortList(n))
    }
    
    func merge(node1 *ListNode,node2 *ListNode)*ListNode {
        // 设置一个空链表,
        node := &ListNode{Val:0}
        current := node
        // 挨个比较俩链表的值,把小的值放到新定义的链表里,排好序
        for node1 != nil && node2 != nil {
            if node1.Val <= node2.Val {
                current.Next,node1 = node1,node1.Next
            } else {
                current.Next,node2 = node2,node2.Next
            }
            current = current.Next
        }
    
        // 两链表可能有一个没走完,所以要把没走完的放到链表的后面
        // 注意,此处跟 数组不一样的是, 数组为什么要循环,因为数组可能一个数组全部走了(比如 12345与6789比较, 前面的全部走完,后面一个没走),另一个可能有多个没走..
        // 链表虽然也有这种可能,但是 node1和node2已经是有序的了,如果另外一个没有走完,直接把next指向node1或者node2就行,因为这是链表
        if node1 != nil {
            current.Next,node1 = node1,node1.Next
        }
        if node2 != nil {
            current.Next,node2 = node2,node2.Next
        }
        return node.Next
    }
    
    

    反转字符串中的单词 III

    func reverseWords(s string) string {
        sr := []rune(s)
        length := len(sr)
        first := 0
        last := 0
    
        for first < length {
            if sr[first] == []rune(" ")[0] {
                reverse(sr, last, first - 1)
                first++
                last = first
            } else {
                first++
            }
        }
        reverse(sr, last, first - 1)
        return string(sr)
    }
    
    func reverse(s []rune, start int, end int) {
        for start < end {
            s[start], s[end] = s[end], s[start]
            start++
            end--
        }
    }
    
    

    大小端的判断

    • 大端模式:数据的高字节保存在内存的低地址
    • 小端模式:数据的高字节保存在内存的高地址
    //若将0x00000001放入计算机中就有两种方法:
    //    此时数据的高地址是:0x00
    
    //—————————————————————>                   小端
    //低地址    01  00  00  00   高地址
    
    //—————————————————————>                   大端
    //高地址    00  00  00  01   低地址
    //————————————————
    package main
    import (
        "fmt"
        "unsafe"
    )
    func main() {
        s := int16(0x1234)  //数据高地址: 0x12
        b := int8(s)
        fmt.Println("int16 size:", unsafe.Sizeof(s))
        //
        if b == 0x34 {
            fmt.Println("little endian")
        } else {
            fmt.Println("big endian")
        }
    }
    

    相关文章

      网友评论

          本文标题:算法题

          本文链接:https://www.haomeiwen.com/subject/hschlltx.html