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)
}