12月组队学习–基础算法篇:枚举、递归、分治、回溯、贪心、位运算(共 14 天)
Task01
4.1枚举算法
- 枚举算法(Enumeration Algorithm):
也称为穷举算法,指的是按照问题本身的性质,一一列举出该问题所有可能的解,并在逐一列举的过程中,将它们逐一与目标状态进行比较以得出满足问题要求的解。在列举的过程中,既不能遗漏也不能重复。
通常用于求解问题规模比较小的问题,或者作为求解问题的一个子算法出现,通过枚举一些信息并进行保存,而这些消息的有无对主算法效率的高低有着较大影响。
- 解题思路:
- 确定枚举对象、枚举范围和判断条件,并判断条件设立的正确性。
- 一一枚举可能的情况,并验证是否是问题的解。
- 考虑提高枚举算法的效率。
- 提高算法效率的方法:
- 抓住问题状态的本质,尽可能缩小问题状态空间的大小。
- 加强约束条件,缩小枚举范围。
- 根据某些问题特有的性质,例如对称性等,避免对本质相同的状态重复求解。
4.2 练习(day1)
1.两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
思路:使用两重循环枚举数组中每一个数,判断所有的和是否等于target。如果出现 ,则说明数组中存在和为target的两个整数,将两个整数的下标输出即可。
from typing import List
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
if i != j and nums[i] + nums[j] == target:
return [i, j]
return []
2. 计数质数
给定整数 n ,返回所有小于非负整数 n 的质数的数量。
思路一:枚举[2,sqrt{x}] 中的所有数。会超时
思路二:埃氏筛,埃拉托斯特尼筛法—要得到自然数 n 以内的全部质数,必须把不大于 根号n 的所有质数的倍数剔除,剩下的就是质数。
算术基本定理:任何一个合数(非质数),都可以以唯一的形式被写成有限个质数的乘积,即分解质因数。
由算术基本定理可知,所有超过根号 n 的合数都可以进行因式分解,其中最小的因子必然为根号 n 以内的一个质数。
所以只需剔除掉根号 n 以内的质数倍数,即排除了 n 以内的所有合数,剩下来的就都是质数。
class Solution:
def isPrime(self, x):
for i in range(2, int(pow(x, 0.5)) + 1):
if x % i == 0:
return False
return True
def countPrimes(self, n: int) -> int:
cnt = 0
for x in range(2, n):
if self.isPrime(x):
cnt += 1
return cnt
class Solution:
def countPrimes(self, n: int) -> int:
# 定义数组标记是否是质数
is_prime = [1] * n
count = 0
for i in range(2, n):
# 将质数的倍数标记为合数
if is_prime[i]:
count += 1
# 从 i*i 开始标记
for j in range(i*i, n, i):
is_prime[j] = 0
return count
3. 统计平方和三元组的数目
一个 平方和三元组 (a,b,c) 指的是满足 a2 + b2 = c2 的 整数 三元组 a,b 和 c 。
给你一个整数 n ,请你返回满足 1 <= a, b, c <= n 的 平方和三元组 的数目。
思路:我们可以枚举整数三元组 (a,b,c) 中的 a和 b,并判断 a2+b2是否为完全平方数,且sqrt{a^2 + b^2} 是否为不大于n的整数。在遍历枚举的同时,维护平方和三元组的数目cnt,如果符合要求,我们将计数加 1。最终,返回该数目作为答案。
class Solution:
def countTriples(self, n: int) -> int:
cnt = 0
for a in range(1, n + 1):
for b in range(1, n + 1):
c = int(sqrt(a * a + b * b + 1))
if c <= n and a * a + b * b == c * c:
cnt += 1
return cnt