Go语言解leetcode(四)

0. 简介

最近在学Go语言,但是没怎么练习,因此在leetcode上用Go语言刷算法题巩固一下Go基础。

1. 在排序数组中查找元素的第一个和最后一个元素:34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode) (leetcode-cn.com)

解题思路:二分查找,当找到了目标元素时,便向前遍历或者向后遍历找出第一个位置和最后一个位置,然后返回。如果找不到则返回{-1,-1}

func searchRange(nums []int, target int) []int {
    if(len(nums)==0){
        return []int{-1,-1}
    }
    left,right := 0,len(nums)-1
    var mid int
    for;left<=right;{
        mid = (left+right)/2
        if(nums[mid]==target){
            tar:=[]int{mid,mid}
            for i:=mid;i>=0;i--{
                if(nums[i]==target){
                    tar[0]=i
                }else{
                    break
                }
            }
            for i:=mid;i<len(nums);i++{
                if(nums[i]==target){
                    tar[1]=i
                }else{
                    break
                }
            }
            return tar
        }
        if(nums[mid]>target){
            right=mid-1
        }
        if(nums[mid]<target){
            left=mid+1
        }        
    }
    return []int{-1,-1}
}

2. 搜索插入位置:35. 搜索插入位置 - 力扣(LeetCode) (leetcode-cn.com)

解题思路:同样采用二分查找,如果找到目标值则直接返回索引,如果当前索引值小于目标值,判断目标值是否小于索引位置后一位的值,如果是,返回当前索引+1;同理如果当前索引值大于目标值,判断目标值是否大于索引位置前一位的值,如果时,返回当前索引。否则,继续循环进行二分查找。

func searchInsert(nums []int, target int) int {
    if(len(nums)==0||target<=nums[0]){
        return 0
    }
    if(nums[len(nums)-1]<target){
        return len(nums)
    }
    left,right:=0,len(nums)-1
    var mid int
    for;left<=right;{
        mid = (left+right)/2
        if(nums[mid]==target){
            break
        }
        if(nums[mid]>target){
            if(mid-1>=0&&nums[mid-1]<target){
                break
            }
            right = mid-1
        }
        if(nums[mid]<target){
            if(mid+1<len(nums)&&nums[mid+1]>target){
                mid++
                break
            }
            left = mid+1
        }
    }
    return mid
}

3. 有效的数独?36. 有效的数独 - 力扣(LeetCode) (leetcode-cn.com)

解题思路:分别构建三个数组,rows,columns,subboxs存放已遍历存在的元素,rows存放每一行的相应数字的出现次数,columns存放每一列的相应数字的出现次数,subboxs则存放每一子3*3格子的相应的数字的出现次数。如果没有出现2,则是有效的数独,反之则不是。

func isValidSudoku(board [][]byte) bool {
    var columns,rows [9][9]int
    var subboxs [3][3][9]int
    for i:=0;i<9;i++{
        for j:=0;j<9;j++{
            if(board[i][j]!='.'){
                rows[i][board[i][j]-'1']++
                columns[j][board[i][j]-'1']++
                subboxs[i/3][j/3][board[i][j]-'1']++
                if(rows[i][board[i][j]-'1']>1||columns[j][board[i][j]-'1']>1){
                    return false
                }
                if(subboxs[i/3][j/3][board[i][j]-'1']>1){
                    return false
                }
            }
        }
    }
    return true
}

4. 解数独?37. 解数独 - 力扣(LeetCode) (leetcode-cn.com)

解题思路:采用递归回溯的思想,上题提到的数组使用bool类型,依次对数独空格进行填充未填充元素(相应数组的相应数字位置上为false),如果成功,则返回true,失败返回false。

func solveSudoku(board [][]byte)  {
    var rows,columns [9][9]bool
    var subboxs [3][3][9]bool
    var space [][2]int
    for i:=0;i<9;i++{
        for j:=0;j<9;j++{
            if board[i][j]!='.'{
                rows[i][board[i][j]-'1']=true
                columns[j][board[i][j]-'1']=true
                subboxs[i/3][j/3][board[i][j]-'1']=true
            }else{
                space = append(space,[2]int{i,j})
            }
        }
    }
    var dfs func(int) bool
    dfs = func(pos int) bool{
        if(pos==len(space)){
            return true
        }
        i,j:=space[pos][0],space[pos][1]
        for digit:=0;digit<9;digit++{
            if !rows[i][digit]&&!columns[j][digit]&&!subboxs[i/3][j/3][digit]{
                rows[i][digit]=true
                columns[j][digit]=true
                subboxs[i/3][j/3][digit]=true
                
                if dfs(pos+1){
                    board[i][j]=byte('1'+digit)
                    return true
                }
                rows[i][digit]=false
                columns[j][digit]=false
                subboxs[i/3][j/3][digit]=false
            }
        }
        return false
    }
    dfs(0)
}

5. 外观数列:38. 外观数列 - 力扣(LeetCode) (leetcode-cn.com)

解题思路:递归的思想,n=1直接返回1,n>=2则调用countAndSay(n-1)获得上一个外观数列,然后对该外观数列进行描述。

byte类型和string类型互相转换:

s1 := "hello"
b := []byte(s1)
s2 := string(b)
func countAndSay(n int) string {
    if(n==1){
        return "1"
    }
    str := countAndSay(n-1)
    num := 1
    lens := len(str)
    temp := make([]byte,0)
    for index:=0;index<lens;index++{
        if index+1<lens&&str[index]==str[index+1]{
            num++
            continue
        }else if index+1<lens&&str[index]!=str[index+1]{
            temp=append(temp,byte('0'+num))
            temp=append(temp,str[index])
            num = 1
        }else{
            temp=append(temp,byte('0'+num))
            temp=append(temp,str[index])
        }
    }
    return string(temp)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值