LeetCode35搜索插入位置
算法思路:我认为这这道题就是考察二分查找法。
常见的二分查找考察的方法有:
这个链接有整理好关于二分查找算法的问题的
说回这道题,这道题需要我们找回数组中target值的索引,如果没有则找到插入位置。其实这个问题就是上面第一个问题—给定一个有序的数组,查找target值是否在数组中,和第三个问题—给定一个有序数组,查找最接近target且大于target的数的下标的结合体。至于应该插在第一位还是最后一位直接可以进行特判(从算法复杂度的角度来说,出现这两种情况是二分查找最差的情况)。
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
# if target < nums[0]:
# return 0
# if target > nums[-1]:
# return len(nums)
low = 0
high = len(nums) - 1
while(low <= high):
middle = low +((high - low)>>1)
if nums[middle] == target:
return middle
elif nums[middle] < target:
low = middle +1
else:
high = middle-1
return high + 1
LeetCode38报数
算法思路:这道题如果读懂了题意,那么就这个问题就简单了。
题意:比如说“1211”,就是一个1,一个2,两个1组成,所以下一个报数我们要输出“111221”,再比如说“111221”,由三个1,二个2,一个1组成,所以下一个我们要输出”312211“
每一项报数都是基于前一项的结果生成的。统计相同的数字,当遇到不相同的数字就要输出结果,然后继续统计下一个数字。我的算法需要注意的是在循环体中当j等于最后一个数了必须要输出当前的字符串。
class Solution:
def countAndSay(self, n: int) -> str:
d = {}
for i in range(1, 31):
d.setdefault(i, "")
d[1] = '1'
d[2] = '11'
for i in range(3, 31):
count = 0
tmp_case = ""
tmp = d[i-1][0]
for j in range(len(d[i-1])):
if tmp == d[i-1][j]:
count += 1
else:
tmp_case = tmp_case+str(count)+str(tmp)
tmp = d[i-1][j]
count = 1
if j == (len(d[i - 1]) - 1):
tmp_case = tmp_case + str(count) + str(tmp)
d[i] = tmp_case
return d[n]
LeetCode2两数相加
算法:就是模拟两个数相加,只是需要考虑不同情况的进位。
具体的进位有普通的进位;两个数位数一样,最后的一位相加后产生进位;两个数位数不一样,比如123,9740中,“3”和“7”相加产生进位,“9”加上之前进位的“1”还要产生进位。这几种进位情况考虑到了就可以了。
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
r = ListNode(0)
p = r
count = 0
while(l1 and l2):
tmp = ListNode(0)
tmp.val = l1.val + l2.val if count == 0 else l1.val + l2.val +1
count = 0
if tmp.val >= 10:
count = 1
tmp.val -= 10
p.next = tmp
p = p.next
l1 = l1.next
l2 = l2.next
if count == 1 and l1 is None and l2 is None:
tmp = ListNode(1)
p.next = tmp
p = p.next
return r.next
while l1:
tmp = ListNode(0)
tmp.val = l1.val if count == 0 else l1.val +1
count = 0
if tmp.val >= 10:
count = 1
tmp.val -= 10
p.next = tmp
p = p.next
l1 = l1.next
if count == 1:
tmp = ListNode(1)
p.next = tmp
while l2:
tmp = ListNode(0)
tmp.val =l2.val if count == 0 else l2.val +1
count = 0
if tmp.val >= 10:
count = 1
tmp.val -= 10
p.next = tmp
p = p.next
l2 = l2.next
if count == 1:
tmp = ListNode(1)
p.next = tmp
return r.next
LeetCode3无重复字符的最长子串
算法思路:最开始写了个O(n^3)的暴力算法。最后看了下讨论里面发现有一个新的思路:
将每一个字符加入一个字符串中,依次检查字符串的字符是否已经存在该子串中,没有加加入,当前子串匹配失败时,子串并不需退回去重新匹配,而是将找到当前子串中失配的位置,从下一位重新开始匹配(因为子串中已经存在个相同的字符了,所以从下一个开始匹配) 每次发生失配就返回当前子串的长度。
tips:当整个字符串检索完毕还要输出还要更新一次无重复字符串长度,因为在for循环中只有发生失配才会更新无重复字符串长度。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
str = ''
max_count = 0
for i in range(len(s)):
if s[i] not in str:
str += s[i]
else:
if max_count < len(str):
max_count = len(str)
str = str[str.index(s[i])+1:]
str += s[i]
if max_count < len(str):
max_count = len(str)
return max_count
LeetCode5最长回文子串
算法思路,这道题有很多种思路,我使用动态规划的方法来解决。
当我们已经判断一个字符串是一个回文串时,假设我们现在已经获得下标从 i i i到 j j j的字符串,即 s i − 1 , j − 1 s_{i-1,j-1} si−1,j−1是一个回文串,如果 s i =    s j s_{i}=\;s_{j} si=sj,那么 s i , j s_{i,j} si,j就是一个回文串,这种情况适用于回文子串长度大于等于3。当长度为1,和2时得初始化。所以我们可以得到一个这样的状态转移方程:
d p [ i ] [ j ] = { 1 d p [ i + 1 ] [ j − 1 ] = 0    a n d    s i = s j 0 d p [ i + 1 ] [ j − 1 ]    ! = 0    o r    s i    ! = s j dp\lbrack i\rbrack\lbrack j\rbrack=\left\{\begin{array}{lc}1&dp\lbrack i+1\rbrack\lbrack j-1\rbrack=0\;and\;s_i=s_j\\0&dp\lbrack i+1\rbrack\lbrack j-1\rbrack\;!=0\;or\;s_i\;!=s_j\end{array}\right. dp[i][j]={10dp[i+1][j−1]=0andsi=sjdp[i+1][j−1]!=0orsi!=sj
class Solution:
def longestPalindrome(self, s: str) -> str:
length = len(s)
if s == "":
return s
dp = [[0 for i in range(length)] for j in range(length)]
max_length = 0
count = 1
for i in range(length): # 初始化dp数组
dp[i][i] = 1
if i < length -1:
if s[i] == s[i+1]:
dp[i][i+1] = 1
#dp[i+1][i] = 1
count = 2
if length < 3:
if count == 2:
return s
elif dp[0][0] == 1:
return s[0]
for len_substring in range(3, length+1): # 枚举每个子串可能的长度
for i in range(length+1-len_substring):
j = i+len_substring-1
if s[i] == s[j] and dp[i+1][j-1] == 1:
dp[i][j] = 1
index_i = 0
index_j = 0
for i in range(length):
for j in range(length):
if dp[i][j] == 1:
count = j-i
if count > max_length:
max_length = count
index_i = i
index_j = j
return s[index_i:index_j+1]