Leetcode每日刷题【中】--Day 21

633. 平方数之和

用两种方式解这道题吧

第一种:双指针

  • 很明显一个数如果能被开放,就会有 0**2 + sqrt(c)**2 == c若满足
  • 那就从这里开始,a == 0, b == int(sqrt(c))进行从两边到中间的进行查找
  • 查找条件:如果左边大于右边,那就是b比较大,b要往左边移动;反之a比较小,a往右边移动
class Solution:
    def judgeSquareSum(self, c: int) -> bool:
        b = int(sqrt(c))
        a = 0
        while a<=b:
            if a*a + b*b == c:
                return True
            elif a*a + b*b > c:
                b -= 1
            elif a*a + b*b < c:
                a -= 1
            
        return False

第二种:费马平方和定理(官方题解)

他说:
一个非负整数 c 如果能够表示为两个整数的平方和,当且仅当 c 的所有形如 4k + 3的质因子的幂均为偶数。

怎么实现:

  • 首先找到因子
  • 其次将所有此因子的幂算出来,再判断是否为要求的因子,判断这个因子的幂是否为偶数
  • 最后判断最后商是否为所说的4k+3的类型,如果是,那么就不是偶数个。
class Solution:
    def judgeSquareSum(self, c: int) -> bool:
        for i in range(2, int(sqrt(c)+1)):
            if c % i != 0:
                continue
            base = 0
            while c % i == 0:
                base += 1
                c //= i
            
            if i % 4 == 3 and base % 2 !=0:
                return False

        return c % 4 != 3 

LCP 28. 采购方案
双指针:先把数组从小到达排好,如果在两个指针的和不大于target,那么这个范围内也不大于target,比较简单。

class Solution:
    def purchasePlans(self, nums: List[int], target: int) -> int:
        nums.sort()
        target_num = 0
        left, right = 0, len(nums)-1
        while left < right:
            if nums[left] + nums[right] <= target:
                target_num += right - left
                left += 1
            if nums[left] + nums[right] > target:
                right -= 1

        return int(target_num % (1e9+7))
剑指 Offer 27. 二叉树的镜像

dfs

这道题并不难,但解释起来却有点麻烦。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def mirrorTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return 
        self.mirrorTree(root.right) # 找到最底层的分支节点(叶子往上一个),交换孩子节点后再进行慢慢回溯
        self.mirrorTree(root.left)
        root.left, root.right = root.right, root.left
        return root
剑指 Offer 31. 栈的压入、弹出序列

比较简单的题目

class Solution:
    def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
        a = []
        i, j = 0, 0
        while True:
            if i < 0 and j >= len(popped) or len(popped) == len(pushed) == 0:  # 模拟栈结束条件
                return True
            elif i >= len(pushed):  # 如果不能,则有一个栈会爆
                return False 
            if i not in a and 0 <= i < len(pushed) and 0 <= j < len(popped):  # 维护i,j在范围内进行
                if pushed[i] != popped[j]:
                    i += 1
                elif pushed[i] == popped[j]:
                    a.append(i)
                    while i in a:
                        i -= 1
                    j +=1
            else:
                i += 1
            
        return True

方法二:还是题解的简单。

解题思路
1.定义一个栈stack作为模拟栈
2.遍历pushed数组的同时将pushed中的元素压入stack模拟压栈过程
3.判断stack的栈顶元素是否与popped数组中的第i个元素相同,相同则弹出stack
4.最后判断stack是否弹空,弹空则返回true,不空则为false

作者:xiao-cai-er
链接

class Solution:
    def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
        stack, i = [], 0
        for num in pushed:
            stack.append(num) # num 入栈
            while stack and stack[-1] == popped[i]: # 循环判断与出栈
                stack.pop()
                i += 1
        return not stack

作者:jyd
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/solution/mian-shi-ti-31-zhan-de-ya-ru-dan-chu-xu-lie-mo-n-2/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JamePrin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值