题目描述:
猜数字游戏的规则如下:
每轮游戏,我都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。
如果你猜错了,我会告诉你,你猜测的数字比我选出的数字是大了还是小了。
你可以通过调用一个预先定义好的接口 int guess(int num) 来获取猜测结果,返回值一共有 3 种可能的情况(-1,1 或 0):
-1:我选出的数字比你猜的数字小 pick < num
1:我选出的数字比你猜的数字大 pick > num
0:我选出的数字和你猜的数字一样。恭喜!你猜对了!pick == num
返回我选出的数字。
题解:
标准的二分查找题
代码(Go):
func guessNumber(n int) int {
high := n
low := 1
mid := (n + 1)/2
for {
if guess(mid) == -1{
high = mid - 1
mid = (high + low)/2
}
if guess(mid) == 1{
low = mid + 1
mid = (high + low)/2
}
if guess(mid) == 0{
return mid
}
}
}
题目描述:
给定一个非空且只包含非负数的整数数组 nums,数组的 度 的定义是指数组里任一元素出现频数的最大值。
你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。
题解:
哈希表,但是我哈希表只存了出现次数,通过再次遍历原数组来获取长度,虽然理论上也是O(n)时间复杂度,但实际上会比较慢,不过空间倒是节省了。官方题解通过哈希表存数组,将起始位置和结束位置一并储存,只需要遍历一次原数组一次哈希表就可以找到,属于是经典的用空间换时间
代码(Go):
func findShortestSubArray(nums []int) int {
var dict = make(map[int]int)
for _,v := range nums{
if _,ok := dict[v];ok{
dict[v]++
}else{
dict[v] = 1
}
}
sce := []int{}
max := 0
for _,v := range dict{
if v > max{
max = v
}
}
for i,v := range dict{
if v == max{
sce = append(sce,i)
}
}
re := len(nums)
for _,vmax := range sce{
temp := max
l := 0
for i,v := range nums{
if vmax == v && temp == 1{
l = i - l + 1
}else if vmax == v && temp == max{
l = i
temp--
}else if vmax == v{
temp--
}
}
if l < re{
re = l
}
}
return re
}
题目描述:
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
题解:
直接哈希表。官方题解用了滑动窗口加哈希表,可以把空间复杂度从O(n)降到O(k),确实没想到
代码(Go):
func containsNearbyDuplicate(nums []int, k int) bool {
var dict = make(map[int]int)
for i,v := range nums{
if value,ok := dict[v];ok{
if i - value <= k{
return true
}
dict[v] = i
}else{
dict[v] = i
}
}
return false
}
题目描述:
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
题解:
之前做过这个类型的题,思路一样,就是一圈一圈遍历。自己写的比较麻烦,评论区有大佬写的很简单,实际上可以用4个变量标记上下左右四个方向的界限,这样代码就非常简洁了。像我的做法只用了一个圈数变量,代码就比较繁琐
代码(Go):
func generateMatrix(n int) [][]int {
var sce = make([][]int,n,n)
for i := 0;i < n;i++{
var scei = make([]int,n,n)
sce[i] = scei
}
num := 1
i,j,k := 0,0,0
for num <= n * n{
if i == k && j == k{ //起点在左上
for i < n - k{ //每打印一圈,横排向右遍历时就要少遍历一个元素
sce[j][i] = num
num++
i++
}
i--
j++ //打印完一个横排后要调整指针指向正确的位置,防止越界或者重复打印
for j < n - k{ //每打印一圈,竖排向下遍历时就要少遍历一个元素
sce[j][i] = num
num++
j++
}
}
j--
if i == n - k - 1 && j == n - k - 1{ //起点在右下
for i >= k + 1{ //起点在右下时先减再赋值,所以k要+1
i--
sce[j][i] = num
num++
}
for j >= k + 2{ //向上遍历时左上角元素已经被打印,所以要少遍历一个元素,k在之前的基础上再+1
j --
sce[j][i] = num
num++
}
}
k++
i = k
j = k
}
return sce
}
整体比较简单,学习了map里装数组的方法,有个坑是map装数组必须数组整体赋值,不能单独改变数组的某一项