剑指 Offer 04. 二维数组中的查找
// 思路1暴力
// 思路2二分查找
// 思路3右上角来看是二叉搜索树
// 这里答案是思路2
func findNumberIn2DArray(matrix [][]int, target int) bool {
if len(matrix) == 0 {
return false
}
m,n := len(matrix), len(matrix[0])
shortDim := min(m,n)
for i:=0;i<shortDim;i++{
findRow := bsRow(matrix,i,target)
findCol := bsCol(matrix,i,target)
if findRow || findCol {
return true
}
}
return false
}
func bsRow(matrix [][]int, row, target int) bool {
l, r := row, len(matrix[0])-1
for l < r {
mid := l+(r-l)/2
if matrix[row][mid] == target {
return true
} else if matrix[row][mid] < target {
l = mid + 1
} else if matrix[row][mid] > target {
r = mid - 1
}
}
if matrix[row][l] == target {
return true
}
return false
}
func bsCol(matrix [][]int, col, target int) bool {
l, r := col, len(matrix)-1
for l < r {
mid := l+(r-l)/2
if matrix[mid][col] == target {
return true
} else if matrix[mid][col] < target {
l = mid + 1
} else if matrix[mid][col] > target {
r = mid - 1
}
}
if matrix[l][col] == target {
return true
}
return false
}
func min(a,b int) int {
if a < b {
return a
}
return b
}
剑指 Offer 11. 旋转数组的最小数字
// 思路1,遍历一遍找最小值。
// 但显然题目不是要我们这样做。
// 思路2:二分查找,略难,要证明
func minArray(numbers []int) int {
// 二分法分治,通过右值与中值比较
n := len(numbers)
l, r := 0, n-1
for l < r {
// 分三种case
mid := l+(r-l)/2
// 1.中值大于右值,如[3 4 5 1 2],最小值一定在右部,所以更新左部
if numbers[mid] > numbers[r] {
l = mid + 1
// 2.中值小于右值,右值一定不是最小值,最小值可能在左部,更新右部
} else if numbers[mid] < numbers[r] {
r = mid
// 3.中值等于右值,题中说可能有重复的值出现,此case right--
} else if numbers[mid] == numbers[r] {
r--
}
}
return numbers[l]
}
剑指 Offer 50. 第一个只出现一次的字符
func firstUniqChar(s string) byte {
var res [26]int
for i:=0;i<len(s);i++{
res[s[i]-'a']++
}
for i:=0;i<len(s);i++{
if res[s[i]-'a']==1{ //这里千万不能写成res[i]==1,因为res前面的元素顺序对应为abcd,他们的值可能为1但是不一定是在s中第一个出现一次的字符
return s[i]
}
}
return ' '
}
func firstUniqChar(s string) byte {
var ans [26]int
for _, v := range s {
ans[v - 'a']++
}
for _, v := range s {
if ans[v-'a'] == 1 {
return byte(v)
}
}
return ' '
}