leetcode刷题周记(四)

题目编号: 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!= 1
232425
去掉无法产生0的, 51052025
再分解, 15 * 25 * 35 * 45 * 55
那些5的倍数的都能构造出 5
2,而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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值