Leedcode day 01 学习笔记

20240915 Leetcode:基础算法篇 ⭐开源内容:https://github.com/datawhalechina/leetcode-notes/blob/main/docs/ch04/index.md

电子网站:https://datawhalechina.github.io/leetcode-notes/#/ch04/index.md

20240918 学习内容 贪心算法之枚举算法

一、学习心得:

一、 枚举算法核心思想:通过列举问题的所有状态,将它们逐一与目标状态进行比较,从而得到满足条件的解。
二、 解题思路:
1 对问题目标状态进行描述
2 对问题所有状态进行描述
3 运用for循环对所有状态进行遍历,寻找到满足条件的解并记录输出
4 直到问题解已经全部找到或者所有状态全部遍历完成。

三、注意事项:尽可能对所有状态遍历前进行优化筛选,减少计算时间空间复杂度。

四、编程方法:
1、类的使用 class solution
2、返回参数表述
(1)、返回一个参数,在定义函数时直接用->“参数类型即可”。
如def twoSum(self, nums: List[int], target: int) -> List[int]:(参见下面代码1)
return “列表”
(2)返回多个参数,则用元组形式。如下面代码中
def find_common_factors(a: int, b: int) ->Tuple[List[int], int]:(参加下面代码2)


二、习题1及其自学拓展

1 习题1 原题要求::两数之和:给定一个整数数组 nums 和一个整数目标值 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 nums[i] + nums[j] == target:
                    return [i, j]
        return []

# 创建 Solution 类的一个实例
solution = Solution()

# 定义输入列表和目标值
num= input("请输入一个由逗号分隔的整数列表(例如:1,2,4,5):") 
nums = [int(num) for num in nums_str.split(",")]  
target_str = input("请输入目标值:")  
target = int(target_str)  

# 调用 twoSum 方法并打印结果
result = solution.twoSum(nums, target)
print(result)  
请输入一个由逗号分隔的整数列表(例如:1,2,4,5):1,3,6,7,4,10
请输入目标值:10
[1, 8]

结果看出,没有把所有数据对输出。所以进行了以下拓展:

2 习题1 自学拓展1:题目要求更改为:要求输出所有的数组中的两数和。

代码更改方法:则需要将return [i,j]处进行修改,不是返回,而是记录,并进行遍历。
from typing import List, Tuple  
  
def two_sum_pairs(nums: List[int], target: int) -> List[Tuple[int, int]]:  
    """  
    返回数组中所有两数之和等于target的数对列表。  
    """  
    pairs = []  # 用于存储数对的列表  
    for i in range(len(nums)):  
        for j in range(i + 1, len(nums)):  
            if nums[i] + nums[j] == target:  
                pairs.append((nums[i], nums[j]))  # 将数对添加到列表中  
    return pairs  
# 获取用户输入  
nums_str = input("请输入一个由逗号分隔的整数列表(例如:1,2,3,4,5):")  
nums = [int(num) for num in nums_str.split(",")]  
  
target_str = input("请输入目标值:")  
target = int(target_str)  
  
# 调用函数并打印结果  
pairs = two_sum_pairs(nums, target)  
for pair in pairs:  
    print(f"({pair[0]}, {pair[1]})")  # 或者简单地使用 print(pair) 来打印元组


请输入一个由逗号分隔的整数列表(例如:1,2,3,4,5):1,2,3,4,5,6,7,8,9,10
请输入目标值:10
(1, 9)
(2, 8)
(3, 7)
(4, 6)

发现没有下标。为此进行下标的同时输出拓展:

3 习题1自学拓展2 在上面代码基础上,将数和下标同时保存和打印

from typing import List, Tuple  
  
def two_sum_pairs_with_indices(nums: List[int], target: int) -> List[Tuple[int, int, int, int]]:  
    """  
    返回数组中所有两数之和等于target的数对及其下标的列表。  
    """  
    pairs_with_indices = []  # 用于存储数对及其下标的列表  
    for i in range(len(nums)):  
        for j in range(i + 1, len(nums)):  
            if nums[i] + nums[j] == target:  
                pairs_with_indices.append((nums[i], nums[j], i, j))  # 将数对及其下标添加到列表中  
    return pairs_with_indices  
  
# 获取用户输入  
nums_str = input("请输入一个由逗号分隔的整数列表(例如:1,2,3,4,5):")  
nums = [int(num) for num in nums_str.split(",")]  
  
target_str = input("请输入目标值:")  
target = int(target_str)  
  
# 调用函数并打印结果  
pairs_with_indices = two_sum_pairs_with_indices(nums, target)  
for pair in pairs_with_indices:  
    print(f"({pair[0]}, {pair[1]}) 在下标 ({pair[2]}, {pair[3]})")
请输入一个由逗号分隔的整数列表(例如:1,2,3,4,5):1,2,3,4,5,6,7,8,9,10
请输入目标值:10
(1, 9) 在下标 (0, 8)
(2, 8) 在下标 (1, 7)
(3, 7) 在下标 (2, 6)
(4, 6) 在下标 (3, 5)

发现没有记录一共有多少对数,于是进行下列拓展

4 习题1 拓展3 ,将数、下标以及有多少对的两个数满足之和为确定值的数目保存和打印

from typing import List, Tuple  
  
def two_sum_pairs_with_indices(nums: List[int], target: int) -> Tuple[List[Tuple[int, int, int, int]], int]:  
    """  
    返回数组中所有两数之和等于target的数对及其下标的列表,以及满足条件的数对总数。  
    """  
    pairs_with_indices = []  # 用于存储数对及其下标的列表  
    total_pairs = 0  # 满足条件的数对总数  
  
    for i in range(len(nums)):  
        if nums[i] > target:  # 跳过大于target的数  
            continue  
        for j in range(i + 1, len(nums)):  
            if nums[i] + nums[j] == target:  
                pairs_with_indices.append((nums[i], nums[j], i, j))  # 添加数对及其下标到列表  
                total_pairs += 1  # 增加总数  
  
    return pairs_with_indices, total_pairs  
  
# 获取用户输入  
nums_str = input("请输入一个由逗号分隔的整数列表(例如:1,2,3,4,5):")  
nums = [int(num) for num in nums_str.split(",")]  
  
target_str = input("请输入目标值:")  
target = int(target_str)  
  
# 调用函数并打印结果  
pairs_with_indices, total_pairs = two_sum_pairs_with_indices(nums, target)  
print(f"Total pairs: {total_pairs}")  
for pair in pairs_with_indices:  
    print(f"({pair[0]}, {pair[1]}) at indices ({pair[2]}, {pair[3]})")
请输入一个由逗号分隔的整数列表(例如:1,2,3,4,5):1,2,3,4,5,6,7,8,9,12,24,8,7,6,5,4,3,2,1
请输入目标值:10
Total pairs: 15
(1, 9) at indices (0, 8)
(2, 8) at indices (1, 7)
(2, 8) at indices (1, 11)
(3, 7) at indices (2, 6)
(3, 7) at indices (2, 12)
(4, 6) at indices (3, 5)
(4, 6) at indices (3, 13)
(5, 5) at indices (4, 14)
(6, 4) at indices (5, 15)
(7, 3) at indices (6, 16)
(8, 2) at indices (7, 17)
(9, 1) at indices (8, 18)
(8, 2) at indices (11, 17)
(7, 3) at indices (12, 16)
(6, 4) at indices (13, 15)

发现记录了相同对数,如(2,8)(8,2)等。且输入数组中有大于目标数的数,需要跳过。于是进行了一下拓展。

5 对数组中大于目标数跳过,且重复对数不记录保存和输出

###对数组中大于目标数的数跳过
from typing import List, Tuple, Set  
  
def two_sum_pairs_filtered(nums: List[int], target: int) -> List[Tuple[int, int, int, int]]:  
    """  
    返回数组中所有两数之和等于target的数对及其下标的列表,  
    跳过大于target的数,并确保不添加重复的数对。  
    """  
    seen_pairs = set()  # 用于跟踪已经遇到的数对(作为元组)  
    pairs_with_indices = []  # 用于存储数对及其下标的列表  
  
    for i in range(len(nums)):  
        if nums[i] > target:  # 跳过大于target的数  
            continue  
        for j in range(i + 1, len(nums)):  
            if nums[j] > target and nums[i] >= target - nums[j]:  # 提前结束内层循环,如果nums[j]已经大于target  
                break  
            # 检查数对是否满足条件且尚未添加  
            if (nums[i], nums[j]) not in seen_pairs and (nums[j], nums[i]) not in seen_pairs and nums[i] + nums[j] == target: 
                #避免重复对数记录。
                seen_pairs.add((nums[i], nums[j]))  # 标记数对为已见  
                pairs_with_indices.append((nums[i], nums[j], i, j))  # 添加数对及其下标到列表  
  
    return pairs_with_indices  
  
# 获取用户输入  
nums_str = input("请输入一个由逗号分隔的整数列表(例如:1,2,3,4,5):")  
nums = [int(num) for num in nums_str.split(",")]  
  
target_str = input("请输入目标值:")  
target = int(target_str)  
  
# 调用函数并打印结果  
pairs_with_indices = two_sum_pairs_filtered(nums, target)  
print(f"Unique pairs found: {len(pairs_with_indices)}")  
for pair in pairs_with_indices:  
    print(f"({pair[0]}, {pair[1]}) at indices ({pair[2]}, {pair[3]})")
请输入一个由逗号分隔的整数列表(例如:1,2,3,4,5):1,2,3,4,5,6,7,8,9,12,14,8,7,6,5,4,3,2,1
请输入目标值:10
Unique pairs found: 4
(1, 9) at indices (0, 8)
(2, 8) at indices (1, 7)
(3, 7) at indices (2, 6)
(4, 6) at indices (3, 5)

上述4,5段结果对比,发现删除了重复项。

from typing import List
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
solution = Solution()
n=10
solution.countPrimes(18)

7

二、习题2 计数质数 描述:给定一个非负整数 n,要求:统计小于n的质数数量。

class Solution:

    def count_primes(self,n)->int:  
        if n <= 2:  
            return 0  

        # 初始化一个布尔数组,用于标记每个数是否为质数  
        # 初始时,除了0和1,其他数都假设为质数  
        is_prime = [True] * n  
        is_prime[0] = is_prime[1] = False  

        # 遍历从2到sqrt(n)的所有数  
        # 因为一个合数的因子一定在sqrt(n)以内  
        for i in range(2, int(n**0.5) + 1):  
            if is_prime[i]:  
                # 如果i是质数,则排除i的所有倍数  
                for j in range(i*i, n, i):  
                    is_prime[j] = False  

        # 统计质数的数量  
        count = sum(is_prime)  
        return count  

# 示例  
n =int(input())
solution=Solution()
print(solution.count_primes(n))  # 输出小于10的质数数量


10
4

三、习题3 三元数组 给出n,找出[1,n]范围内的三元数,a,b,c满足 a 2 + b 2 = c 2 a^2+b^2=c^2 a2+b2=c2

class Solution:
    def find_pythagorean_triples(self,n)->List[int]:  
        triples = []  
        for a in range(2, int(n**0.5) + 1):  # 只遍历到sqrt(n),因为c=m^2+n^2会增长得很快  
            for b in range(1, a): 
                for c in range(n):
                    if c <= n and a*a+b*b==c*c:  # 确保c在范围内,这个条件实际上可以优化掉,因为m的范围已经限制了c  
                        triples.append((a, b, c))  
        # 排序输出(可选)  
        triples.sort()  
        return triples  
solution=Solution()

n =int(input()) # 示例n值  
triples = solution.find_pythagorean_triples(n)  
for triple in triples:  
    print(triple)
100
(4, 3, 5)
(8, 6, 10)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值