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/