leetcode 11,14,15題記錄
阿新 • • 發佈:2021-01-15
技術標籤:演算法
第11題:盛最多水的容器
這道題一開始是有點懵的,因為看樣子很像一道動態規劃,最後看了評論才發現是對撞指標。
- 一開始得先找到切入點,盛水最多的容器,則說明兩個邊之外如果有更高的邊,則可以將邊移至那一條更高的邊,所以可以從陣列的首尾開始往中間逼近。
- 逼近的規則又如何定義?保留最大值!!!有貪心的感覺,保留最大的邊,較小的一邊往中間逼近。
func maxArea(height []int) int {
if len(height) < 2{return 0}
maxL := 0
left := 0
right := len(height) - 1
for (left < right){
min := 0
if height[left] < height[right]{
min = height[left]
}else{
min = height[right]
}
if l := min * (right - left) ; l > maxL{
maxL = l
}
if height[left] < height[right] {
left++
}else{
right--
}
}
return maxL
}
第14題:最長公共字首
這個也是一道簡單題,沒有更好的演算法,只有迭代字串,實時更新最長字首。
func longestCommonPrefix(strs []string) string {
if len(strs) == 0 {return ""}
if len(strs) == 1 {return strs[0]}
s := strs[0]
for _ , j := range strs{
for i , k := range j {
if i >= len(s) || string(s[i]) != string(k){
s = s[:i]
break
}
}
if len(s) > len(j) {s = s[:len(j)]}
}
return s
}
第15題:三數之和
這類找不到O(n2)以下方法的題總是讓人不舒服。
- 先準備一個快排,將陣列排好序。
- 開始迭代,將迭代控制在0值之前,因為三數相加等於0,最小值必須小於等於0,如果迭代值與上一個數相等則跳過,以免得到重複結果。
- 設定對撞指標:L,R(今天的對撞指標有點多),如果三數相加大於0則減小引數:R–,小於0則增大引數:L++,直到L == R為止。
- 如果三數相加等於0,加三數裝進容器,並且開始去重,以免取到重複的結果,最後L++,R–。
func threeSum(nums []int) [][]int {
if len(nums) < 3{return [][]int{}}
quickSort(nums,0,len(nums)-1)
var n [][]int
L := 0
R := len(nums) - 1
for i, j := range nums{
if j > 0 {break}
if i > 0 && nums[i-1] == j {continue}
L = i + 1
R = len(nums) - 1
for (L < R) {
if nums[L] + nums[R] + j == 0 {
n = append(n,[]int{j,nums[L],nums[R]})
for(L < R && nums[L+1] == nums[L]){L++}
for(L < R && nums[R-1] == nums[R]){R--}
L++
R--
}else if nums[L] + nums[R] + j > 0 { R-- }else{ L++ }
}
}
return n
}
func quickSort(arr []int, start, end int) {
if start < end {
i, j := start, end
key := arr[(start+end)/2]
for i <= j {
for arr[i] < key {
i++
}
for arr[j] > key {
j--
}
if i <= j {
arr[i], arr[j] = arr[j], arr[i]
i++
j--
}
}
if start < j {
quickSort(arr, start, j)
}
if end > i {
quickSort(arr, i, end)
}
}
}