leetcode 16,20,21 題記錄
阿新 • • 發佈:2021-01-15
技術標籤:演算法
第16題:最接近的三數之和
基本就是三數之和那題的翻版了,注意一些小細節就行,比如更新最小值之後不需要額外的步幅,因為在三數之和中是需要一個精確值,得到精確值之後就可以更新L和R,而本題不是求精確值,有可能在此基礎上繼續走下去還能有更好的結果,除非這個值已經等於0了。
func threeSumClosest(nums []int, target int) int {
sort.Ints(nums)
n := int(^uint32(0)>>1)
L := 0
R := 0
for i, j := range nums{
L = i+1
R = len(nums) - 1
if i != 0 && nums[i-1] == j {continue}
for (L < R){
s := nums[L] + nums[R] + j
if abs(s - target) < abs(n - target){n = s}
if s > target{
for R > 1 && nums[R-1] == nums[R]{R-- }
R--
}else if s < target{
for L < len(nums) - 2 && nums[L+1] == nums[L]{L++}
L++
}else{
break
}
}
}
return n
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}
第20題:有效的括號
有效括號最主要是思路,左括號和右括號中間要麼什麼都沒有,要麼有N對成對的括號,否則括號就會被拆開不成對。
我是用的是堆疊的方式搭配switch時間複雜度是O(n),空間複雜度也是O(n)。評論的題解中有更為好看的方法:直接將成對的括號替換成空值即可,到最後能得到一個空string,基礎思路也和我之前說的一樣,左括號和右括號中間要麼什麼都沒有,要麼有N對成對的括號,那麼最中間肯定是一對沒有阻礙的成對括號,不過複雜度可能更高一些。
func isValid(s string) bool {
var n []int32
var ok bool
for _, j := range s{
switch string(j) {
case "(":
n = append(n, 1)
case "{":
n = append(n, 2)
case "[":
n = append(n, 3)
case ")":
if n,ok = v(n,1);!ok{return false}
case "}":
if n,ok = v(n,2);!ok{return false}
case "]":
if n,ok = v(n,3);!ok{return false}
default:
return false
}
}
return len(n) == 0
}
func v(n []int32, x int32) ([]int32,bool){
if len(n) == 0 {return nil ,false}
if n[len(n)-1] != x{
return nil,false
}else {
n = n[:len(n)-1]
}
return n,true
}
第21題:合併兩個有序連結串列
這題很明顯的遞迴,將較小本節點返回,next接下一個遞迴返回就行
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
if l1 == nil {return l2}
if l2 == nil {return l1}
if l1.Val <= l2.Val{
l1.Next = mergeTwoLists(l1.Next,l2)
return l1
}else{
l2.Next = mergeTwoLists(l1,l2.Next)
return l2
}
}