733.图像渲染-简单
题目描述;
有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。
你也被给予三个整数 sr , sc 和 newColor 。你应该从像素 image[sr][sc] 开始对图像进行 上色填充 。
为了完成 上色工作 ,从初始像素开始,记录初始坐标的 上下左右四个方向上 像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应 四个方向上 像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为 newColor 。
最后返回 经过上色渲染后的图像 。
题解:
一看到题就想到递归去做,最后用了一堆if完成了。看官方题解是用非递归的深度优先搜索和广度优先搜索做的,第一次做图相关的题,做的时候完全没意识到这是个图,只是靠逻辑思维做的题,看完官方题解再仔细看看我的代码才发现这不就是递归的深度优先搜索吗。
代码(Go):
func floodFill(image [][]int, sr int, sc int, color int) [][]int {
oldcolor := image[sr][sc]
if oldcolor == color {
return image
}
image[sr][sc] = color
if sr - 1 >= 0{
if image[sr - 1][sc] == oldcolor{
floodFill(image, sr - 1, sc, color)
}
}
if sr + 1 <len(image) {
if image[sr + 1][sc] == oldcolor{
floodFill(image, sr + 1, sc, color)
}
}
if sc - 1 >= 0 {
if image[sr][sc - 1] == oldcolor{
floodFill(image, sr, sc - 1, color)
}
}
if sc + 1 < len(image[0]) {
if image[sr][sc + 1] == oldcolor{
floodFill(image, sr, sc + 1, color)
}
}
return image
}
125.验证回文串-简单
题目描述:
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
题解:
双指针遍历字符串原地判断,空间复杂度O(1),用了个字符串大小写转换的API,不然还挺麻烦的。
代码(Go):
func isPalindrome(s string) bool {
if s == ""{
return true
}
l := len(s)
s = strings.ToLower(s)
i,j := 0,l - 1
for i < j{
for !isalnum(s[i]) && i < j{
i++
}
for !isalnum(s[j]) && i < j{
j--
}
if s[i] != s[j]{
return false
}
i++
j--
}
return true
}
func isalnum(ch byte) bool {
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
}
111.二叉树的最小深度-简单
题目描述:
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
题解:
直接递归就可以了,用if else判断一下特殊情况
代码(Go):
func minDepth(root *TreeNode) int {
if root == nil{
return 0
}
if root.Left == nil{
return minDepth(root.Right) + 1
}
if root.Right == nil{
return minDepth(root.Left) + 1
}
return min(minDepth(root.Left),minDepth(root.Right)) + 1
}
func min(x int,y int) int{
if x < y{
return x
}
return y
}
剑指 Offer II 001. 整数除法-简单
题目描述:
给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 ‘*’、除号 ‘/’ 以及求余符号 ‘%’ 。
注意:
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231−1]。本题中,如果除法结果溢出,则返回 231 − 1
题解:
一开始只想到暴力解,因为乘除取余都不能用,就只想到除法的本质,先把两数取绝对值,再用for循环去不断地减,直到下一次减会减少到小于0停止。但是写完代码我就猜到会超时,因为如果商很大的情况下,要做非常多次数的循环,最后果然超时。然后我就想,在只用能用加减的情况下怎样才能加快这个for循环减法的过程呢,我发现我的代码只用了减,没有用到加,最后想到了计算机网络里的一个原理:慢开始。被除数每减一次除数就通过除数自己加自己的方式翻倍,直到被除数减除数即将小于0,再从一开始重新进行这个过程,直到被除数减最开始的除数都即将小于0,循环结束。
官方题解使用了二分法,有一种方法官方叫类二分查找,原理和慢开始差不多,都是通过倍增的方式降低时间复杂度,但通过建立一个数组将倍增的值暂存起来,通过空间换时间的方式可以进一步降低时间复杂度。
(这题我做的时候就觉得不像简单题,一看下面主站同一道题果然标的是中等,和前面我做过的一道题一样,都被剑指Offer从中等题降级成简单题了)
代码(Go):
func divide(a int, b int) int {
re := 0
flag := 0
temp := 1
if (a >= 0 && b>= 0) || (a < 0 && b < 0){
flag = 1
}
a = int(math.Abs(float64(a)))
b = int(math.Abs(float64(b)))
b0 := b
for a - b0 >= 0{
b = b0
temp = 1
for a - b >= 0{
a = a - b
b = b + b
re = re + temp
temp = temp + temp
}
}
if ((re > int(math.Pow(2,31) -1)) && flag == 1) || ((re > int(math.Pow(2,31))) && flag == 0){
return int(math.Pow(2,31) - 1)
}
if flag == 1{
return re
}else{
return 0-re
}
}
总结
前三道题都比较常规,最后一个题比较有意思,官方的二分法也很巧妙,这两次做了两道主站中等题,感觉也是可以尝试的,没到毫无头绪的地步,好好想想依然能做出来。不过由于目前解题较慢,效率不高,暂时打算再做一周简单题,五一结束开始每天一道中等三道简单,逐渐从简单题过渡到中等题。