题目编号: 155、160、167、168、169、171、172
155. 最小栈
我的解法:
同步双栈法,data栈存储数据,helper栈存储最小值
初始化:将两个栈均初始为空
入栈:data栈先入栈,若helper栈为空或当前入栈元素值小于helper栈顶元素(即当前入栈元素为最小值),则元素入helper栈,否则helper当前栈顶元素再次入helper栈
出栈:若栈不空,则helper出栈,data出栈
取栈顶:若data栈不空,返回当前栈顶元素
取最小值:返回helper当前栈顶元素
class MinStack(object):
def __init__(self):
"""
initialize your data structure here.
"""
self.data = []
self.helper = []
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.data.append(x)
if len(self.helper) == 0 or x <= self.helper[-1]:
self.helper.append(x)
else:
self.helper.append(self.helper[-1])
def pop(self):
"""
:rtype: None
"""
if self.data:
self.helper.pop()
return self.data.pop()
def top(self):
"""
:rtype: int
"""
if self.data:
return self.data[-1]
def getMin(self):
"""
:rtype: int
"""
if self.helper:
return self.helper[-1]
160.相交链表
我的解法:
创建两个指针 pA 和 pB,分别初始化为链表 A 和 B 的头结点。然后让它们向后逐结点遍历。
当 pA 到达链表的尾部时,将它重定位到链表 B 的头结点 ; 类似的,当 pB 到达链表的尾部时,将它重定位到链表 A 的头结点。
若在某一时刻 pA 和 pB 相遇,则 pA/pB 为相交结点。
想弄清楚为什么这样可行, 可以考虑以下两个链表: A={1,3,5,7,9,11} 和 B={2,4,9,11},相交于结点 9。 由于 B.length (=4) < A.length (=6),pB 比 pA 少经过 222 个结点,会先到达尾部。将 pB 重定向到 A 的头结点,pA 重定向到 B 的头结点后,pB 要比 pA 多走 2 个结点。因此,它们会同时到达交点。
如果两个链表存在相交,它们末尾的结点必然相同。因此当 pA/pB 到达链表结尾时,记录下链表 A/B 对应的元素。若最后元素不相同,则两个链表不相交。
# 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
"""
if not headA or not headB:
return None
pA = headA
pB = headB
while pA != pB:
pA = headB if (pA == None) else pA.next
pB = headA if (pB == None) else pB.next
return pA
167. 两数之和 II - 输入有序数组
我的解法:
双指针法
若left、right指针的值之和等于目标值,则返回index1和index2
若left、right指针的值之和小于目标值,则left指针向后移一位
反之right指针向前移一位
当left>right时,说明未找到,返回空
class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
left = 0
right = len(numbers) - 1
while left < right:
if numbers[left] + numbers[right] == target:
return left+1, right+1
if numbers[left] + numbers[right] < target:
left += 1
if numbers[left] + numbers[right] > target:
right -= 1
return None
168. Excel表列名称
我的解法:
类似进制转换,10转26
divmod() 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)
chr()函数返回值是当前整数对应的 ASCII 字符
class Solution(object):
def convertToTitle(self, n):
"""
:type n: int
:rtype: str
"""
res = ""
while n:
n -= 1
n,y = divmod(n,26)
res = chr(y+65) + res
return res
169.求众数
我的解法:
因为题目中众数的个数始终大于n/2,所以可以先对数组进行排序,然后取中位数,一定为众数
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums.sort()
return nums[len(nums)/2]
171. Excel表列序号
我的解法:
同168题,类似进制转换,26转10
class Solution(object):
def titleToNumber(self, s):
"""
:type s: str
:rtype: int
"""
res = 0
bit = 1
for a in s[::-1]:
res += (ord(a)-64)*bit
bit *= 26
return res
172.阶乘后的零
我的解法:
能产生0的情况只有 52=10,其他情况分解后也是这个,2的数目要远多于5,所以问题就转变为求求5的个数
比如说 25!= 123…2425
去掉无法产生0的, 51052025
再分解, 15 * 25 * 35 * 45 * 55
那些5的倍数的都能构造出 52,而25有两层5
所以只要 n//5就能得出第一层的5的个数,剩下1 * 2 * 3 * 4 * 5
上面的结果再除以5就是下一层的5的个数
最终5+1=6
class Solution(object):
def trailingZeroes(self, n):
"""
:type n: int
:rtype: int
"""
p = 0
while n >= 5:
n = n // 5
p += n
return p