Go语言解leetcode(六)

0. 简介

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

1. 字母异位词分组?49. 字母异位词分组 - 力扣(LeetCode) (leetcode-cn.com)

解题思路:对需要进行分组的单词进行重新排序,排序规则按照字母顺序设置,这里因为针对操作的类型是[]byte,sort包中并没有提供相关的排序函数,因此需要自己实现比较规则:

for _,str := range strs{
    s := []byte(str)
    sort.Slice(s,func(i,j int) bool{
        return s[i]<s[j]
    })
    sortedStr := string(s)
    //这里的sortedStr即为重新排完序的字符串
}

使用map存储分组的结果,key值为重排序后的字符串,value值为string切片,每次进行一次重排序,都将当前处理元素加入重排序后单词所在的切片中。等到将所有的单词处理完后,再遍历map中的所有切片并将其添加到目标位置并返回即可。

func groupAnagrams(strs []string) [][]string {
    mapStr := make(map[string][]string)
    for _,str := range strs{
        s := []byte(str)
        sort.Slice(s,func(i,j int) bool{
            return s[i]<s[j]
        })
        sortedStr := string(s)
        mapStr[sortedStr] = append(mapStr[sortedStr],str)
    }
    ans := make([][]string,0,len(mapStr))
    for _,value := range mapStr{
        ans = append(ans,value)
    }
    return ans
}

2. Pow(x,n)?50. Pow(x, n) - 力扣(LeetCode) (leetcode-cn.com)

解题思路:采用递归的思想,比如:2^9 = 2^4 * 2^4 * 2,对于指数为单数的情况,我们多乘以一个本身的数,对于指数为双数的情况,我们直接将目标次方的一半次方的计算结果做平方运算即可。

func myPow(x float64, n int) float64 {
    if n>0{
        return pow(x,n)
    }
    return 1/pow(x,-n)
}

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

3. N皇后?51. N 皇后 - 力扣(LeetCode) (leetcode-cn.com)

解题思路:参考解数独题的思路,这里我们使用三个数组,column,leftToright,rightToleft分别表示列的占用情况,左上到右下斜列的占用情况,右上到左下斜列的占用情况,采用递归回溯的思路,如果满足条件则将其加入到最终答案中。

var column []bool
var leftToright []bool
var rightToleft []bool

func solveNQueens(n int) [][]string {
    
    column = make([]bool, n)
	leftToright = make([]bool, 2*n-1)
	rightToleft = make([]bool, 2*n-1)

    ans:=make([][]string,0)
    temp:=make([]int,0)
    find(0,n,&ans,&temp)
    return ans
}

func find(index int,n int,ans *[][]string,temp *[]int) {
    if index == n {
		str := strings.Repeat(".", n)
        tar := make([]string,0)
        for _,val := range *temp{
            bytes := []byte(str)
            bytes[val-1] = 'Q'
            tar = append(tar,string(bytes))
        }
        *ans = append(*ans,tar)
		return
	}
	for i := 0; i < n; i++ {
		if !column[i] && !leftToright[i-index+n-1] && !rightToleft[index+i] {
			column[i] = true
			leftToright[i-index+n-1] = true
			rightToleft[index+i] = true
			*temp = append(*temp, i+1)
			find(index+1, n, ans, temp)
			*temp = (*temp)[0 : len(*temp)-1]
			rightToleft[index+i] = false
			leftToright[i-index+n-1] = false
			column[i] = false
		}
	}
}

这里需要注意的是,因为是将column,leftToright,rightToleft定义为全局变量,而在全局变量中只可以声明而不可以赋值(先前赋值了但是报错了),所以赋值的操作在函数调用中实现。另外一个点是,左上到右下斜列的分组,应该使用 i(列) - index(行) + n - 1,需要加上n-1是为了防止超出数组范围,右上到左下斜列的分组,应该使用 i + index。

4. N皇后II:52. N皇后 II - 力扣(LeetCode) (leetcode-cn.com)

解题思路:题解思路与上一题一致,只不过判断成功的处理逻辑为答案计数加一。

var column []bool
var leftToright []bool
var rightToleft []bool
var result int

func totalNQueens(n int) int {
    column = make([]bool,n)
    leftToright = make([]bool,2*n-1)
    rightToleft = make([]bool,2*n-1)
    result = 0
    find(0,n)
    return result
}

func find(index int,n int){
    if index==n{
        result++;
        return
    }
    for i:=0;i<n;i++{
        if !column[i]&&!leftToright[i-index+n-1]&&!rightToleft[i+index]{
            column[i]=true
            leftToright[i-index+n-1]=true
            rightToleft[i+index]=true
            find(index+1,n)
            rightToleft[i+index]=false
            leftToright[i-index+n-1]=false
            column[i]=false
        }
    }
}

5. 最大子数组和:53. 最大子数组和 - 力扣(LeetCode) (leetcode-cn.com)

解题思路:我们先假设最终的结果为正数,那么最终结果数组的两边必定为非正数,否则最终结果数组还可以再大。因此我们对数组做累加操作,如果累加大于记录最大值,更新,如果小于0,则将累加和重新归0。

func maxSubArray(nums []int) int {
    result := math.MinInt32
    val := 0
    for _,num := range nums{
        val = val+num
        if val>result{
            result = val
        }
        if val<0{
            val=0
        }
    }
    return result
}

这里要注意的是,即使数组内全为负数,也可以得到相应的结果,即最大的那个负数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值