目录
1.给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
2.给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。
3.给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
4.给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
5.给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
7.设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
1.给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
在杨辉三角中,每个数是它左上方和右上方的数的和。
示例:
输入: 5
输出:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
方法一:
class Solution(object):
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
def builtls(ls):
newls=[1]*(len(ls)+1)
#因为最左端和最右端都是1,所以不进行更新,只更新中间部分
for i in range(1,len(ls)):
newls[i]=ls[i-1]+ls[i]
return newls
if numRows==0:
return []
retr=[[1]]
for i in range(1,numRows):
retr.append(builtls(retr[-1]))
return retr
方法二:
class Solution:
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
result = []
for i in range(numRows):
#第几行就有几个数,先构造出
now = [1]*(i+1)
#当i大于等于2时,now会发生变化
if i >= 2:
for n in range(1,i):
now[n] = pre[n-1]+pre[n]
#将当前行加到列表里
result.append(now)
pre = now
return result
2.给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。否则输出0
方法一:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
#动态规划 前i天的最大收益
#= max{前i-1天的最大收益,第i天的价格-前i-1天中的最小价格}
if prices==[]:
return 0
maxp=0
min_getin=prices[0]
for i in range(len(prices)):
min_getin=min(min_getin,prices[i])
maxp=max(maxp,prices[i]-min_getin)
return maxp
方法二:但是执行时间长,复杂度大
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
differ=0
for i in range(len(prices)):
if max(prices[i:])-prices[i]>differ:
differ=max(prices[i:])-prices[i]
return differ
3.给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
#根据题目的意思,当天卖出以后,当天还可以买入,
#所以算法可以直接简化为只要今天比昨天大,就卖出。
profit = 0
for day in range(len(prices)-1):
differ = prices[day+1] - prices[day]
if differ > 0:
profit += differ
return profit
4.给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
示例 1:
输入: "A man, a plan, a canal: Panama" 输出: true
class Solution:
def isPalindrome(self, s: str) -> bool:
s = ''.join(filter(str.isalnum,s)).lower()
return s==s[::-1]
5.给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1] 输出: 1
方法一:但是比较耗时
class Solution:
def singleNumber(self, nums: List[int]) -> int:
while nums!=None:
temp=nums.pop()
if temp in nums:
nums.remove(temp)
else:
return temp
方法二:
class Solution:
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
a = 0
#除了某个元素只出现一次以外,其余每个元素均出现两次。
#因此所有的数除奇次以外,异或后等于0,而0^0=0
for num in nums:
a = a ^ num
return a
6.给定一个链表,判断链表中是否有环。
方法一:
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
save = set()
cur = head
while cur is not None:
if cur in save:
return True
else:#将当前指针加到集合中
save.add(cur)
cur = cur.next
#如果cur为空,则一定无环
return False
类似方法
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
list_id = []
while head:
if id(head) in list_id:
return True
list_id.append(id(head))
head = head.next
return False
方法二:快慢指针法:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def hasCycle(self, head):
fast =head
low = head
while fast is not None and fast.next is not None:
fast = fast.next
if fast == low or fast.next==low:
return True
fast = fast.next
low = low.next
return False
7.设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) -- 将元素 x 推入栈中。
- pop() -- 删除栈顶的元素。
- top() -- 获取栈顶元素。
- getMin() -- 检索栈中的最小元素。
示例:
MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> 返回 -3. minStack.pop(); minStack.top(); --> 返回 0. minStack.getMin(); --> 返回 -2.
class MinStack(object):
def __init__(self):
"""
initialize your data structure here.
"""
self.stack = []
self.minstack = []
def push(self, x):
"""
:type x: int
:rtype: void
"""
self.stack.append(x)
if self.minstack == [] or x <= self.minstack[-1]:
self.minstack.append(x)
def pop(self):
"""
:rtype: void
"""
#如果弹出的是最小值在末尾,则将最小值列表和原来列表
#中的最小元素都弹出
if self.stack != []:
if self.stack[-1] == self.minstack[-1]:
self.minstack.pop()
self.stack.pop()
def top(self):
"""
:rtype: int
"""
if self.stack != []:
return self.stack[-1]
else:
return None
def getMin(self):
"""
:rtype: int
"""
if self.minstack != []:
return self.minstack[-1]
else:
return None
8.编写一个程序,找到两个单链表相交的起始节点
方法一:
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
save = set()
curA=headA
while curA is not None:
save.add(curA)
curA=curA.next
cur = headB
while cur is not None:
if cur in save:
return cur
else:#将当前指针加到集合中
cur = cur.next
#如果cur为空,则一定无环
return None
方法二:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
#同时对A和B进行遍历, 并且让到达末尾的指针指向另一个链表的头结点.
#例如A: 6->7->4->5; B: 1->2->3->4->5
#遍历时会相交于4 (67451234, 12345674).
#不相交,因为最后会两个串都粘贴对方,所以不相交的话,q,p都是None
if not headA or not headB:
return None
p,q = headA,headB
while p!=q:
p = p.next if p else headB
q = q.next if q else headA
return p