补充题 (原创或者改动题目)
有序数组每个数平方后,不同数字的个数,时间O(n) 空间O(1) (byte)
给你一个有序整数数组,数组中的数可以是正数、负数、零,请实现一个函数,这个函数返回一个整数:返回这个数组所有数的平方值中有多少种不同的取值。举例:
nums = {-1,1,1,1},
那么你应该返回的是:1。因为这个数组所有数的平方取值都是1,只有一种取值
nums = {-1,0,1,2,3}
你应该返回4,因为nums数组所有元素的平方值一共4种取值:1,0,4,9
func main(){
fmt.Println(findDiff([]int{-1,3,3}))
fmt.Println(findDiff([]int{-1,1,1,1}))
}
func findDiff(nums []int)int{
//双指针,两边绝对值最大的
l,r:=0,len(nums)-1
pre:=-1
res:=0
for l<=r{ //条件是相等,因为最后一个数也需要判断是否和pre相等
if abs(nums[l])>abs(nums[r]){
if abs(nums[l])!=pre{
res++
pre = abs(nums[l])
}
l++
}else{
if abs(nums[r])!=pre{
res++
pre = abs(nums[r])
}
r--
}
}
return res
}
func abs(x int)int{
if x<0{
return -x
}else{
return x
}
}
最大数(byte)
数组A中给定可以使用的1~9的数,返回由A数组中的元素组成的小于n的最大数。
例如A={1, 2, 4, 9},x=2533,返回2499
func main(){
nums:=[]int{1,2,4,9}
fmt.Println(getMax(nums,2533))
fmt.Println(getMax([]int{9},2000))
fmt.Println(getMax([]int{6,7,8},1200))
}
//num 选数,组合成小于target的最大数
func getMax(nums []int,target int)int{
strs:=strconv.Itoa(target)
sort.Ints(nums)
flag:=false //标记是否已经取小于的数字
imax:=nums[len(nums)-1]
res:=0
for i:=0;i<len(strs);i++{
if flag {
res = res*10 + imax
continue
}
idx:=search(nums,int(strs[i]-'0'))
if nums[idx]!=int(strs[i]-'0') { //不等于则左边为小于的值
if idx-1 < 0 {
//直接返回小于位数的数字
for j := 1; j < len(strs); j++ {
res = res*10 + imax
}
return res
}
res = res*10 + nums[idx-1]
flag = true
}else{
res = res*10 + nums[idx] //有相等元素直接取
}
}
return res
}
//返回小于等于的下标
func search(nums []int,target int)int{
l,r:=0,len(nums)
for l<r{
mid:=l+(r-l)/2
if nums[mid]<target{
l = mid+1
}else if nums[mid]>=target{
r = mid
}
}
return l
}
类似498对角线遍历(不同点在于是从左下朝右上角一个方向遍历,不需要更换方向,实现如下)
import "fmt"
//矩阵单个方向遍历,从左下向右上角.
func find(matrix [][]int)[]int{
res:=[]int{}
m,n:=len(matrix),len(matrix[0])
//上半部分
for i:=0;i<m;i++{
col:=0
for j:=i;j>=0;j--{ //x轴到0才停止
res = append(res,matrix[j][col])
col++
}
}
//下半部分,比上半部分少1,并且y从1开始
for i:=1;i<n;i++{
row:=m-1 //行
for j:=i;j<n&&row>=0;j++{ //y轴到末尾才停止,row越界也要停止
res = append(res,matrix[row][j])
row--
}
}
return res
}
func main(){
nums:=[][]int{
{1,2,3},
{4,5,6},
{7,8,9},
}
arr:=[][]int{
{1,2,3,4,1,3},
{5,6,7,8,4,5},
{9,1,2,3,7,8},
}
fmt.Println(find(nums))
fmt.Println(find(arr))
}
打印从1到最大的n位数(byte) (考虑n太大,生成的数字超出int32)
- dfs生成 从1-n,不包含0,不需要考虑0开头的问题
var res []string
var path []byte
func main(){
path = make([]byte,26) //26位字母
dfs(0,2) //2位数字最大值
fmt.Println(res)
}
func dfs(index int,n int){
if index==n{
res = append(res,string(path))
return
}
for i:=1;i<10;i++{
path[index] = byte('0'+i)
dfs(index+1,n)
}
}