3201. 找出有效子序列的最大长度 I

ops/2024/12/21 22:08:05/

Powered by:NEFU AB-IN

Link

文章目录

  • 3201. 找出有效子序列的最大长度 I
    • 题意
    • 思路
    • 代码
    • 拓展

3201. 找出有效子序列的最大长度 I

  • 题意

给你一个整数数组 nums。

nums 的子序列 sub 的长度为 x ,如果其满足以下条件,则称其为 有效子序列:

(sub[0] + sub[1]) % 2 == (sub[1] + sub[2]) % 2 == … == (sub[x - 2] + sub[x - 1]) % 2
返回 nums 的 最长的有效子序列 的长度。

一个 子序列 指的是从原数组中删除一些元素(也可以不删除任何元素),剩余元素保持原来顺序组成的新数组。

  • 思路

  1. 贪心:最长有效子序列有三种可能:

    • 全都是奇元素
    • 全都是偶元素
    • 奇偶元素交替
      代码注意:
    • odd := sum(x & 1 for x in nums), 是海象表达式,赋值的同时返回值
    • sum((x & 1) ^ (y & 1) for x, y in std.pairwise(nums)) 这句话非常的巧妙,首先获取每一对相邻的元素,然后 (x & 1) ^ (y & 1) 会比较 x 和 y 的奇偶性,算和是计算所有相邻元素对的奇偶性差异
      • 比如 2 1 3 3 4 6,生成 [(2, 1), (1, 3), (3, 3), (3, 4), (4, 6)],其中只有 (2, 1), (3, 4) 是奇偶性差异的 pair
        • 当出现 (0, 1) 的时候,如果再出现一个 (0, 1),期间一定会夹杂着一个 (1, 0) 对
      • 但显然这个是 (0, 1) (1, 0),即使 1 和 3 不同,但是我们可以选择一个,那么序列就可以为 214 或者 234,长度为 2 + 1 = 3
      • 所以 1 + sum((x & 1) ^ (y & 1) for x, y in pairwise(nums)) 等价于 奇偶交替的最长子序列长度
  2. dfs + 记忆化搜索
    为了考虑所有可能的初始状态,代码调用 dfs 函数四次,分别对应四种不同的初始状态:

    dfs(0, 0, 1):从索引 0 开始,初始奇偶性为偶数,需要的奇偶性变化为 奇
    dfs(0, 0, 0):从索引 0 开始,初始奇偶性为偶数,需要的奇偶性变化为 偶
    dfs(0, 1, 0):从索引 0 开始,初始奇偶性为奇数,需要的奇偶性变化为 偶
    dfs(0, 1, 1):从索引 0 开始,初始奇偶性为奇数,需要的奇偶性变化为 奇

    其实也是上面一样的思路,只不过用的dfs
    lru_cache 类似 cache,可以实现记忆化搜索

  • 代码

'''
Author: NEFU AB-IN
Date: 2024-06-30 10:30:18
FilePath: \LeetCode\CP404\b\b.py
LastEditTime: 2024-07-01 20:39:53
'''
# 3.8.19 import
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from datetime import datetime, timedelta
from functools import lru_cache
from heapq import heapify, heappop, heappush, nlargest, nsmallest
from itertools import combinations, compress, permutations, starmap, tee
from math import ceil, fabs, floor, gcd, log, sqrt
from string import ascii_lowercase, ascii_uppercase
from sys import exit, setrecursionlimit, stdin, stdout
from typing import Any, Dict, Generic, List, TypeVar, UnionTYPE = TypeVar('TYPE')# Data structure
class SA(Generic[TYPE]):def __init__(self, x: TYPE, y: TYPE):self.x = xself.y = ydef __lt__(self, other: 'SA[TYPE]') -> bool:return self.x < other.xdef __eq__(self, other: 'SA[TYPE]') -> bool:return self.x == other.x and self.y == other.ydef __repr__(self) -> str:return f'SA(x={self.x}, y={self.y})'# Constants
N = int(2e5 + 10)  # If using AR, modify accordingly
M = int(20)  # If using AR, modify accordingly
INF = int(2e9)
OFFSET = int(100)# Set recursion limit
setrecursionlimit(INF)# Read
def input(): return stdin.readline().rstrip("\r\n")  # Remove when Mutiple data
def read(): return map(int, input().split())
def read_list(): return list(read())# Func
class std:letter_to_num = staticmethod(lambda x: ord(x.upper()) - 65)  # A -> 0num_to_letter = staticmethod(lambda x: ascii_uppercase[x])  # 0 -> Aarray = staticmethod(lambda x=0, size=N: [x] * size)array2d = staticmethod(lambda x=0, rows=N, cols=M: [std.array(x, cols) for _ in range(rows)])max = staticmethod(lambda a, b: a if a > b else b)min = staticmethod(lambda a, b: a if a < b else b)removeprefix = staticmethod(lambda s, prefix: s[len(prefix):] if s.startswith(prefix) else s)removesuffix = staticmethod(lambda s, suffix: s[:-len(suffix)] if s.endswith(suffix) else s)@staticmethoddef find(container: Union[List[TYPE], str], value: TYPE):"""Returns the index of value in container or -1 if value is not found."""if isinstance(container, list):try:return container.index(value)except ValueError:return -1elif isinstance(container, str):return container.find(value)@staticmethoddef pairwise(iterable):"""Return successive overlapping pairs taken from the input iterable."""a, b = tee(iterable)next(b, None)return zip(a, b)# ————————————————————— Division line ——————————————————————class Solution:def maximumLength(self, nums: List[int]) -> int:return max(odd := sum(x & 1 for x in nums),len(nums) - odd,1 + sum((x & 1) ^ (y & 1) for x, y in std.pairwise(nums)))def maximumLength(self, nums: List[int]) -> int:@lru_cache(None)def dfs(index, expected_parity, original_parity):# 递归终止条件:如果索引达到数组末尾,返回0if index == len(nums):return 0# 当前元素奇偶性符合预期if nums[index] % 2 == expected_parity:# 将当前元素加入子序列,并继续递归下一个元素# 更新expected_parity为(original_parity - expected_parity) % 2return 1 + dfs(index + 1, (original_parity - expected_parity) % 2, original_parity)else:# 当前元素不符合预期,不加入子序列,继续递归下一个元素return dfs(index + 1, expected_parity, original_parity)# 考虑所有可能的初始状态return max(dfs(0, 0, 1), dfs(0, 0, 0), dfs(0, 1, 0), dfs(0, 1, 1))
  • 拓展

当2变为k时,可以用dp解决

'''
Author: NEFU AB-IN
Date: 2024-06-30 10:30:18
FilePath: \LeetCode\CP404\c\c.py
LastEditTime: 2024-07-01 22:18:53
'''
# 3.8.19 import
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from datetime import datetime, timedelta
from functools import lru_cache
from heapq import heapify, heappop, heappush, nlargest, nsmallest
from itertools import combinations, compress, permutations, starmap, tee
from math import ceil, fabs, floor, gcd, log, sqrt
from string import ascii_lowercase, ascii_uppercase
from sys import exit, setrecursionlimit, stdin, stdout
from typing import Any, Dict, Generic, List, TypeVar, UnionTYPE = TypeVar('TYPE')# Data structure
class SA(Generic[TYPE]):def __init__(self, x: TYPE, y: TYPE):self.x = xself.y = ydef __lt__(self, other: 'SA[TYPE]') -> bool:return self.x < other.xdef __eq__(self, other: 'SA[TYPE]') -> bool:return self.x == other.x and self.y == other.ydef __repr__(self) -> str:return f'SA(x={self.x}, y={self.y})'# Constants
N = int(2e5 + 10)  # If using AR, modify accordingly
M = int(20)  # If using AR, modify accordingly
INF = int(2e9)
OFFSET = int(100)# Set recursion limit
setrecursionlimit(INF)# Read
def input(): return stdin.readline().rstrip("\r\n")  # Remove when Mutiple data
def read(): return map(int, input().split())
def read_list(): return list(read())# Func
class std:letter_to_num = staticmethod(lambda x: ord(x.upper()) - 65)  # A -> 0num_to_letter = staticmethod(lambda x: ascii_uppercase[x])  # 0 -> Aarray = staticmethod(lambda x=0, size=N: [x] * size)array2d = staticmethod(lambda x=0, rows=N, cols=M: [std.array(x, cols) for _ in range(rows)])max = staticmethod(lambda a, b: a if a > b else b)min = staticmethod(lambda a, b: a if a < b else b)removeprefix = staticmethod(lambda s, prefix: s[len(prefix):] if s.startswith(prefix) else s)removesuffix = staticmethod(lambda s, suffix: s[:-len(suffix)] if s.endswith(suffix) else s)@staticmethoddef find(container: Union[List[TYPE], str], value: TYPE):"""Returns the index of value in container or -1 if value is not found."""if isinstance(container, list):try:return container.index(value)except ValueError:return -1elif isinstance(container, str):return container.find(value)@staticmethoddef pairwise(iterable):"""Return successive overlapping pairs taken from the input iterable."""a, b = tee(iterable)next(b, None)return zip(a, b)# ————————————————————— Division line ——————————————————————class Solution:def maximumLength(self, nums: List[int], k: int) -> int:n = len(nums)dp = std.array2d(0, n, k + OFFSET)if n <= 2:return nfor j in range(k):dp[0][j] = 1res = 0for i in range(n):for j in range(i):dp[i][(nums[i] + nums[j]) % k] = std.max(dp[i][(nums[i] + nums[j]) % k], dp[j][(nums[i] + nums[j]) % k] + 1)res = std.max(res, max(dp[i]))return res

http://www.ppmy.cn/ops/54729.html

相关文章

【LeetCode:2742. 给墙壁刷油漆 + 递归 + 记忆化搜索 + dp】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Node.js全栈指南:看官方文档的艺术

上回我们说到啊&#xff0c;创建了一个极简的 Web 服务&#xff0c;监听了端口&#xff0c;设置了正确的编码&#xff0c;成功地在浏览器看到了返回的内容 “你好&#xff0c;世界&#xff01;”。 那么本章节呢&#xff0c;我们通过一个简单的例子来分析&#xff0c;如何有效…

对于业务中的一些生效时间处理理解

在业务中常会遇到对于一些事件、规则等等有设置生效时间&#xff0c;它们无非也就两种大类型 时间是具体的时间&#xff0c;比如&#xff08;2024-06-28 10:00:00到 2024-06-29 20:00:00&#xff09; 这种类型可以采取的方式有很多&#xff0c;比如可以直接转换为时间戳比较 …

cube-studio开源一站式机器学习平台,在线ide,jupyter,vscode,matlab,rstudio,ssh远程连接,tensorboard

全栈工程师开发手册 &#xff08;作者&#xff1a;栾鹏&#xff09; 一站式云原生机器学习平台 前言 开源地址&#xff1a;https://github.com/tencentmusic/cube-studio cube studio 腾讯开源的国内最热门的一站式机器学习mlops/大模型训练平台&#xff0c;支持多租户&…

代码随想三刷动态规划篇5

代码随想三刷动态规划篇5 377. 组合总和 Ⅳ题目代码 57. 爬楼梯&#xff08;第八期模拟笔试&#xff09;题目代码 322. 零钱兑换题目代码 279. 完全平方数题目代码 377. 组合总和 Ⅳ 题目 链接 代码 class Solution {public int combinationSum4(int[] nums, int target) {…

使用 c# + vue 制作 DevExpress 报表

theme: smartblue 一、下载 DevExpress 下载地址: https://docs.devexpress.com/XtraReports/400128/product-information/devexpress-reporting-installer 二、创建报表 选择你要放置的文件夹&#xff0c;依次选择 “Add”&#xff0c; “New Item...” 第一次显示时可能没有详…

NoSQL之Redis配置与管理

目录 一、关系型数据库和非关系型数据库 1.关系型数据库 2.非关系型数据库 3.关系型数据库和非关系型数据库区别 二、Redis 1.Redis简介 2.Redis 的优点 3.Redis 使用场景 4.Redis的数据类型 5.哪些数据适合放入缓存中&#xff1f; 6.Redis为什么这么快&#xff1f;…

GPT-5或于一年半后发布?浅谈智能的飞跃与未来

一、前言 IT之家6月22日消息&#xff0c;在美国达特茅斯工程学院周四公布的采访中&#xff0c;OpenAI首席技术官米拉穆拉蒂被问及GPT-5是否会在明年发布&#xff0c;给出了肯定答案并表示将在一年半后发布。 技术的风暴从未停止&#xff0c;人工智能作为这场风暴中的旋风&…