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
}
这里要注意的是,即使数组内全为负数,也可以得到相应的结果,即最大的那个负数。