牛客刷题day10
文章目录
1.进制转换
题目
给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数
输入7,2 返回值"111"
解题思路
除N取余,然后倒序排列,高位补零。
说M是32位整数,所以有可能是负数和0,如果是0的话直接返回,如果是负数,就先转化成正数,最后再加上符号位。
核心代码
class Solution:
def solve(self , M , N ):
if M==0:
return 0
# write code here
if M<0:
M=-M
sign ='-'
else:
sign=''
Str=''
while M:
rest = M%N
if rest>=10:
rest = chr((rest-10)+ord('A'))
Str+=str(rest)
M=M//N
Str=sign+Str[::-1]
return Str
2.链表指定区间 反转
题目
将一个链表\ m m 位置到\ n n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。
例如:
给出的链表为 1→2→3→4→5→NULL, m=2,n=4m=2,n=4,
返回 1→4→3→2→5→NULL.
注意:
给出的 mm,nn 满足以下条件:
链表长度1≤m≤n≤链表长度
输入:{1,2,3,4,5},2,4
返回值:{1,4,3,2,5}
解题思路
先找到n的位置,使用双指针,在m-n区间使用头插法将链表反转
核心代码
class Solution:
def reverseBetween(self , head , m , n ):
# write code here
if not head:
return head
newHead = ListNode(0)
newHead.next =head
cur,pre = head,newHead
for i in range(m-1):
pre =cur
cur = cur.next
for j in range(n-m):
temp = cur.next
cur.next =temp.next
temp.next = pre.next
pre.next = temp
return newHead.next
3.最长公共子序列
题目
给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如果最长公共子序列为空,则输出-1。
示例1
输入
“1A2C3D4B56”,“B1D23CA45B6A”
返回值
“123456”
说明
"123456"和“12C4B6”都是最长公共子序列,任意输出一个
解题思路
动态规划
核心代码
class Solution:
def LCS(self, s1, s2):
# write code here
m, n = len(s1), len(s2)
# if m > n:
# m, n = n, m
# s1, s2 = s2, s1
dp =[[''] *(n +1) for _ in range(m+1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if (s2[j - 1] == s1[i - 1]):
dp[i][j] = dp[i - 1][j - 1] + s2[j - 1]
else:
if len(dp[i - 1][j]) > len(dp[i][j - 1]):
dp[i][j] = dp[i - 1][j]
else:
dp[i][j] = dp[i][j - 1]
if dp[-1][-1]:
return dp[-1][-1]
else:
return -1
今天运行代码发现一个问题,应该是python的问题,创建二维数组要用
dp =[[’’] *(n +1) for _ in range(m+1)]
切不可使用
dp =[[’’] (n +1) ](m+1)
下面创建数组,当m太大的时候会出现bug,最好不要使用
4.数组中未出现的最小正整数
题目
给定一个无序数组arr,找到数组中未出现的最小正整数
例如arr = [-1, 2, 3, 4]。返回1
arr = [1, 2, 3, 4]。返回5
[要求]
时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)
示例1
输入
[-1,2,3,4]
返回值
1
解题思路
1.常规思路
先排序,再找确实值
2.我们先找出数组最小值和最大值的索引,然后计算其最小值到最大值的和
再求出数组和。差值就是缺少的那个正数。如果差值为零证明缺失的是最后的那个整数
核心代码
1.常规思路
class Solution:
def minNumberdisappered(self, arr):
if not arr:
return 0
# write code here
m =len(arr)
num = 0
arr.sort()
for i in range(m):
if arr[i] > 0:
num += 1
if arr[i] > num:
return num
return arr[-1] + 1
2.符合题意
class Solution:
def minNumberdisappered(self, arr):
# write code here
sum_num = 0
sum_index = 0
min_num, max_num = arr[0], arr[0]
for num in arr:
sum_num += num
min_num = min(min_num, num)
max_num = max(max_num, num)
for index in range(min_num, max_num + 1):
sum_index += index
if sum_index - sum_num == 0:
return max_num + 1
else:
return sum_index - sum_num
5.表达式求值
题目
请写一个整数计算器,支持加减乘三种运算和括号。
示例1
输入
“1+2”
返回值
3
解题思路
算法:栈
-
用栈保存各部分计算的和
-
遍历表达式,使用 sign 变量记录运算符,初始化是 ‘+’;使用 number 变量记录字符串中的数字部分的数字值是多少
2.1遇到空格时跳过
2.2 遇到数字时继续遍历求这个完整的数字的值,保存到 number 中
2.3 遇到左括号时递归求这个括号里面的表达式的值 先遍历找到对应的右括号,因为可能里面还嵌有多对括号,使用一个变量 counterPartition 统计括号对数直到变量为 0
2.4 遇到运算符时或者到表达式末尾时,就去计算上一个运算符并把计算结果 push 进栈,然后保存新的运算符到 sign 如果是 + ,不要计算,push 进去 如果是 - ,push 进去负的当前数 如果是 ×、÷ ,pop 出一个运算数和当前数作计算 -
最后把栈中的结果求和即可
核心代码
class Solution:
def solve(self, s):
# write code here
stack = []
sign = '+'
number = 0
i = 0
while i < len(s):
c = s[i]
if c == ' ':
continue
if c.isdigit():
number = number * 10 + int(c)
if c == "(":
j = i + 1
counterpatition = 1
while counterpatition > 0:
if s[j] == "(":
counterpatition += 1
if s[j] == ")":
counterpatition -= 1
j += 1
number = self.solve(s[i + 1:j])
i = j - 1
if not c.isdigit() or i == len(s) - 1:
if sign == '+':
stack.append(number)
elif sign == '-':
stack.append(-1 * number)
elif sign == '*':
stack.append(stack.pop(-1) * number)
elif sign == '/':
stack.append(stack.pop(-1) / number)
number = 0
sign = c
i += 1
ans = 0
while stack:
ans += stack.pop()
return ans
6.判断一个链表是否为回文结构
题目
给定一个链表,请判断该链表是否为回文结构。
示例1
输入
[1,2,2,1]
返回值
true
解题思路
1.思路一
遍历链表,将链表的值存储在数组或者字符串,转为判断字符串或者数组是否为回文结构
2.思路二
找到链表的中间节点,将链表后半段反转,再入链表前半段做对比
核心代码
思路一
class Solution:
def isPail(self , head ):
# write code here
if not head:
return True
stack=[]
while head:
stack.append(head.val)
head =head.next
len_stack = len(stack)
mid = len_stack//2
for i in range(mid):
if stack[i]!= stack[len_stack-i-1]:
return False
return True
思路二
class Solution:
def isPail(self , head ):
# write code here
if head == None or head.next == None: return True
slow,fast = head,head#慢指针、快指针
#找到中间节点
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
#找到中间节点后让fast指针指向slow->next;
fast = slow.next
slow.next = None
newList = None
#进行后半部分的翻转
while fast != None:
newList = fast.next
fast.next = slow
slow = fast
fast = newList
#判断回文
newList = slow
fast = head
while fast != None and newList != None:
if fast.val != newList.val:return False
fast = fast.next
newList = newList.next
return True