algorithm/problem/leetcode/5
5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
123输入:s = "babad"输出:"bab"解释:"aba" 同样是符合题意的答案。
示例 2:
12输入:s = "cbbd"输出:"bb"
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成
区间dp:记忆化搜索
dfs函数也可以返回boolean值来实现
123456789101112131415161718192021222324252627282930class Solution { int L = -1, R = -1, RES = -1; public String longestPalindrome(String s) { char cs[] = s.toCharArray(); int n = cs.length; String res = ""; ...
algorithm/problem/leetcode/516
516. 最长回文子序列
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
示例 1:
123输入:s = "bbbab"输出:4解释:一个可能的最长回文子序列为 "bbbb" 。
示例 2:
123输入:s = "cbbd"输出:2解释:一个可能的最长回文子序列为 "bb" 。
提示:
1 <= s.length <= 1000
s 仅由小写英文字母组成
区间dp(记忆化搜索)
123456789101112131415161718class Solution { public int longestPalindromeSubseq(String s) { char cs[] = s.toCharArray(); int n = cs.length; int memo[][] = new int[n][n]; ...
algorithm/problem/leetcode/2926
2926. 平衡子序列的最大和(2448)
给你一个下标从 0 开始的整数数组 nums 。
nums 一个长度为 k 的 子序列 指的是选出 k 个 下标 i0 < i1 < ... < ik-1 ,如果这个子序列满足以下条件,我们说它是 平衡的 :
对于范围 [1, k - 1] 内的所有 j ,nums[ij] - nums[ij-1] >= ij - ij-1 都成立。
nums 长度为 1 的 子序列 是平衡的。
请你返回一个整数,表示 nums 平衡 子序列里面的 最大元素和 。
一个数组的 子序列 指的是从原数组中删除一些元素(也可能一个元素也不删除)后,剩余元素保持相对顺序得到的 非空 新数组。
示例 1:
12345678输入:nums = [3,3,5,6]输出:14解释:这个例子中,选择子序列 [3,5,6] ,下标为 0 ,2 和 3 的元素被选中。nums[2] - nums[0] >= 2 - 0 。nums[3] - nums[2] >= 3 - 2 。所以,这是一个平衡子序列,且它的和是所有平衡子序列里最大的。包 ...
algorithm/problem/leetcode/2127
2127. 参加会议的最多员工数
一个公司准备组织一场会议,邀请名单上有 n 位员工。公司准备了一张 圆形 的桌子,可以坐下 任意数目 的员工。
员工编号为 0 到 n - 1 。每位员工都有一位 喜欢 的员工,每位员工 当且仅当 他被安排在喜欢员工的旁边,他才会参加会议。每位员工喜欢的员工 不会 是他自己。
给你一个下标从 0 开始的整数数组 favorite ,其中 favorite[i] 表示第 i 位员工喜欢的员工。请你返回参加会议的 最多员工数目 。
示例 1:
1234567输入:favorite = [2,2,1,2]输出:3解释:上图展示了公司邀请员工 0,1 和 2 参加会议以及他们在圆桌上的座位。没办法邀请所有员工参与会议,因为员工 2 没办法同时坐在 0,1 和 3 员工的旁边。注意,公司也可以邀请员工 1,2 和 3 参加会议。所以最多参加会议的员工数目为 3 。
示例 2:
123456789输入:favorite = [1,2,0]输出:3解释:每个员工都至少是另一个员工喜欢的员工。所以公司邀请他们所有人参加会议的前提是所有人都参加了会议。座位安排同图 ...
algorithm/problem/leetcode/2935
2935. 找出强数对的最大异或值 II(2349)
给你一个下标从 0 开始的整数数组 nums 。如果一对整数 x 和 y 满足以下条件,则称其为 强数对 :
|x - y| <= min(x, y)
你需要从 nums 中选出两个整数,且满足:这两个整数可以形成一个强数对,并且它们的按位异或(XOR)值是在该数组所有强数对中的 最大值 。
返回数组 nums 所有可能的强数对中的 最大 异或值。
注意,你可以选择同一个整数两次来形成一个强数对。
示例 1:
1234输入:nums = [1,2,3,4,5]输出:7解释:数组 nums 中有 11 个强数对:(1, 1), (1, 2), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (3, 5), (4, 4), (4, 5) 和 (5, 5) 。这些强数对中的最大异或值是 3 XOR 4 = 7 。
示例 2:
1234输入:nums = [10,100]输出:0解释:数组 nums 中有 2 个强数对:(10, 10) 和 (100, 100) 。这些强数对中的最大异或值是 10 ...
algorithm-tree-01
0-1树
概念
0-1树是字典树的一个变种,每个树节点只有0和1两个孩子,可以用来维护一些数字的异或和。
相关题解
421. 数组中两个数的最大异或值
2935. 找出强数对的最大异或值 II(2349)
algorithm/problem/leetcode/421
421. 数组中两个数的最大异或值
给你一个整数数组 nums ,返回 nums[i] XOR nums[j] 的最大运算结果,其中 0 ≤ i ≤ j < n 。
示例 1:
123输入:nums = [3,10,5,25,2,8]输出:28解释:最大运算结果是 5 XOR 25 = 28.
示例 2:
12输入:nums = [14,70,53,83,49,91,36,80,92,51,66,70]输出:127
提示:
1 <= nums.length <= 2 * 10^5
0 <= nums[i] <= 2^31 - 1
按位哈希:对于每一位,用哈希表记录之前出现的数,用哈希表判断newRes是否可能成立
如果 a⊕b=newAns,那么两边同时异或 b,由于 b⊕b=0,所以得到 a=newAns⊕b(相当于把两数之和代码中的减法改成异或)
这样就可以一边枚举 b,一边在哈希表中查找 newAns⊕b 了。
12345678910111213141516171819202122class Solution { public ...
algorithm/problem/leetcode/139
139. 单词拆分
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
**注意:**不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
123输入: s = "leetcode", wordDict = ["leet", "code"]输出: true解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
示例 2:
1234输入: s = "applepenapple", wordDict = ["apple", "pen"]输出: true解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。 注意,你可以重复使 ...
algorithm/problem/leetcode/715
715. Range 模块
Range模块是跟踪数字范围的模块。设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们。
半开区间 [left, right) 表示所有 left <= x < right 的实数 x 。
实现 RangeModule 类:
RangeModule() 初始化数据结构的对象。
void addRange(int left, int right) 添加 半开区间 [left, right),跟踪该区间中的每个实数。添加与当前跟踪的数字部分重叠的区间时,应当添加在区间 [left, right) 中尚未跟踪的任何数字到该区间中。
boolean queryRange(int left, int right) 只有在当前正在跟踪区间 [left, right) 中的每一个实数时,才返回 true ,否则返回 false 。
void removeRange(int left, int right) 停止跟踪 半开区间 [left, right) 中当前正在跟踪的每个实数。
示例 1:
12345678910111213输入["Ran ...
algorithm/problem/leetcode/307
307. 区域和检索 - 数组可修改
给你一个数组 nums ,请你完成两类查询。
其中一类查询要求 更新 数组 nums 下标对应的值
另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 ,其中 left <= right
实现 NumArray 类:
NumArray(int[] nums) 用整数数组 nums 初始化对象
void update(int index, int val) 将 nums[index] 的值 更新 为 val
int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 (即,nums[left] + nums[left + 1], ..., nums[right])
示例 1:
1234567891011输入:["NumArray", "sumRange", "update", "sumRange" ...