LeetCode50題第一天

2021-10-14 12:58:21 字數 4827 閱讀 7425

演算法思路:

由於鍊錶是從低位到高位, 我們可以逐位相加, 某一位為(l1.val + l2.val) % 10

由於存在進製問題, 需要設定乙個變數作為進製, 其值為(l1.val + l2.val) // 10

如果在中途某個鍊錶到頭了, 那麼就可以推出第一層迴圈, 迴圈單獨的鍊錶即可(這裡可以使用將none補零, 來簡化**, 但是演算法的複雜度並未簡化)

# definition for singly-linked list.

# class listnode(object):

# def __init__(self, val=0, next=none):

# self.val = val

# self.next = next

class

solution

(object):

defaddtwonumbers

(self, l1, l2)

:"""

:type l1: listnode

:type l2: listnode

:rtype: listnode

"""c =

0#這裡新建立乙個鍊錶作為結果, head為其頭結點

head = listnode(

) mid = head

# 第一層迴圈

while l1 is

notnone

and l2 is

notnone

: p = listnode(

) p.val =

(l1.val + l2.val + c)%10

c =int(

(l1.val + l2.val + c)/10

) mid.

next

= p mid = mid.

next

l1 = l1.

next

l2 = l2.

next

#第二層迴圈

while l1 is

notnone

: p = listnode(

) p.val =

(l1.val + c)%10

c =int(

(l1.val + c)/10

) mid.

next

= p mid = mid.

next

l1 = l1.

next

while l2 is

notnone

: p = listnode(

) p.val =

(l2.val + c)%10

c =int(

(l2.val + c)/10

) mid.

next

= p mid = mid.

next

l2 = l2.

next

#防止出現高位進製

if c ==1:

p = listnode(1)

mid.

next

= p return head.

next

複雜度: 設煉表長度分布為m, n, 由於該演算法遍歷了兩個鍊錶這複雜度為o(m+n)

解法一先找到兩個陣列的長度, 然後遍歷找到中位數即可

如果是奇數個, 那麼就直接返回, 如果是偶數個, 那麼就返回它與它前乙個樹的和的平均數

double findmediansortedarrays(int* nums1, int nums1size, int* nums2, int nums2size)

}if (!flag)

}return (nums1size + nums2size) & 1 ? res * 1.0 : (pre + res) * 1.0 / 2;

}

複雜度分析: 假設兩個陣列長度分別為m, n, 本演算法的遍歷次數為(n + m) / 2, 所以複雜度為o(m + n)

解法二演算法思想:

使用二分思想

本題相當於在兩個有序陣列中查詢中位數, 可以使用二分方法依次排除不可能的取值

假設查詢值為k, 那麼a[0-k/2]和b[0-k/2]絕對不會是結果, 我們可以利用這個性質, 遞迴求得結果

double findmediansortedarrays(int* nums1, int nums1size, int* nums2, int nums2size) else 

k = k - (offset + 1);

if (a1 >= nums1size) return flag ? nums2[a2 + k - 1] : (nums2[a2 + k - 1] + nums2[a2 + k]) * 1.0 / 2;

if (a2 >= nums2size) return flag ? nums1[a1 + k - 1] : (nums1[a1 + k - 1] + nums1[a1 + k]) * 1.0 / 2;

}if (flag)

if (nums1[a1] > nums2[a2]) else

}

複雜度: 假設兩個陣列長度為m, n, 由於使用二分查詢, 複雜度為o(log(m + n))

解法一:

這個解法是我以前的**, 具體思路如下

從最長字元開始尋找, 往短的方向尋找, 這樣如果找到即可返回, 如果從最短開始, 由於不知道是否是最大的, 那麼繼續尋找

class

solution

(object):

deflongestpalindrome

(self, s)

:"""

:type s: str

:rtype: str

"""if s =="":

return

""if

len(s)==1

:return s

i =0 j =

len(s)

str=

""while

len(

str)

<

(j - i +1)

:while

len(

str)

<

(j - i +1)

: j = s.rfind(s[i]

, i, j)

iflen

(str

)<

(j - i +1)

and s[i:j]

== s[j:i:-1

]:str= s[i:j+1]

j =len(s)

i +=

1return

str

複雜度分析: 本演算法相當於暴力破解, 在最好的情況需要一次, 最壞情況需要n的平方次

解法二:

馬拉車演算法

馬拉車演算法核心思想: 用過去的求過的的最長回文子串加速未知的, 本質是動態規劃

class

solution

(object):

deflongestpalindrome

(self, s)

:"""

:type s: str

:rtype: str

"""s = s.replace("",

"#")

# 將字串馬拉車化

c =-1

# 初始化對稱中心

r =-1

# 初始化最小右邊界

max1 =

0# 記錄最大右邊界

cmax = c # 記錄最大邊界半徑

arr =[0

]*(len

(s)-1)

# 遍歷字串

for i in

range(0

,len

(s)-1)

:# 核心加速**: 可以直接根據i'的邊界半徑求出i點的在r內的邊界半徑

arr[i]

=min

(r - i, arr[

2* c - i]

)if r > i else

1# 繼續擴充套件i的邊界半徑

while

(i + arr[i]

<

len(s)

and i - arr[i]

>-1

):if s[i + arr[i]

]== s[i - arr[i]]:

arr[i]+=1

else

:break

# 如果i的邊界半徑大於已經記錄的邊界半徑, 那麼就更新邊界半徑和對稱中心

if arr[i]

> max1:

max1 = arr[i]

cmax = i

# 更新邊界半徑和對稱中心

if arr[i]

+ i > r:

r = i + arr[i]

c = i

str= s[cmax - max1 +

1: cmax + max1 -1]

print

(cmax, max1)

print

(str

)return

str.replace(

"#",

"")

leetcode刷題第一天

給你兩個 非空 的鍊錶,表示兩個非負的整數。它們每位數字都是按照 逆序 的方式儲存的,並且每個節點只能儲存 一位 數字。請你將兩個數相加,並以相同形式返回乙個表示和的鍊錶。你可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。class solution def addtwonumbers se...

LeetCode騰訊精選練習50 第一天

題目4 給定兩個大小為 m 和 n 的正序 從小到大 陣列 nums1 和 nums2。請你找出並返回這兩個正序陣列的中位數 題解 class solution def findmediansortedarrays self,nums1 list int nums2 list int float s...

leetcode刷題筆記 第一天

題目說明 給定乙個 haystack 字串和乙個 needle 字串,在 haystack 字串中找出 needle 字串出現的第乙個位置 從0開始 如果不存在,則返回 1。解題思路 首先判斷needle是否在haystack中,如果存在則返還needle所在位置。如果不存在,則返還 1。def s...