竞赛190
定长子串中元音的最大数目
给你字符串 s 和整数 k 。
请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。
英文中的 元音字母 为(a, e, i, o, u)。
示例 1:
输入:s = "abciiidef", k = 3 输出:3 解释:子字符串 "iii" 包含 3 个元音字母。
示例 2:
输入:s = "aeiou", k = 2 输出:2 解释:任意长度为 2 的子字符串都包含 2 个元音字母。
示例 3:
输入:s = "leetcode", k = 3 输出:2 解释:"lee"、"eet" 和 "ode" 都包含 2 个元音字母。
示例 4:
输入:s = "rhythms", k = 4 输出:0 解释:字符串 s 中不含任何元音字母。
示例 5:
输入:s = "tryhard", k = 4 输出:1
提示:
1 <= s.length <= 10^5s由小写英文字母组成1 <= k <= s.length
// 超时,即使是避免掉重复 y.includes(s[i]), 特殊情况还是超时,明显就是时间复杂度过高问题,但有不知怎么减少
/**
* @param {string} s
* @param {number} k
* @return {number}
*/
var maxVowels = function(s, k) {
let i=0, len = s.length;
// let arr = s.split('')
let y = ['a', 'e', 'i', 'o', 'u'];
let res = 0;
let arr = new Array(len).fill(0);
for(let i=0; i<len; i++){
if(y.includes(s[i])){
arr[i] = 1
// count++
}
}
while(i<len-2){
let count = 0;
arr.slice(i, i+k).forEach(f=>{
if(f===1){
count++
}
})
res = Math.max(res, count)
if(res===k){
return k
}
i++;
}
// while(i<len-2){
// let count = 0;
// if(y.includes(s[i])){
// s.slice(i, i+k).split('').forEach(f=>{
// if(y.includes(f)){
// count++
// }
// })
// res = Math.max(res, count)
// if(res===k){
// return k
// }
// // i++;
// }
// i++;
// }
return res;
};
思路: 很多地方会用数组做一个前面一个和后面一个的关系式子,就像dp那样
记录某个到某个索引处共出现的次数
// 就是之前数组不仅要记录是否是”原因字母“,好要记录,到某个索引处之前共有几个”原因字母“,其实当时也想某个”原因字母“必须知道它前后是不是,是有影响的,我当时会想到有没有最大连续的。
//但是呢,高手用数组记录出现”元音字母“出现的次数。
// 第二个循环,arr[i]=n1, 之后k个每个加1,最大也就是n1+k,所以最大差值也就是k
while(i<=len-k){
res = Math.max(res, arr[i+k]-arr[i]);
i++;
}
/** * @param {string} s * @param {number} k * @return {number} */ var maxVowels = function(s, k) { let t = ['a','e','i','o','u']; let len = s.length; let arr = new Array(len+1).fill(0); for(let i=1; i<=len; i++){ arr[i] = arr[i-1]+(~t.indexOf(s[i-1])?1:0); } console.log(arr) let res = 0; for(let i = k; i <= len; ++ i){ res = Math.max(res, arr[i]-arr[i-k]); } return res };
// 思路:遍历整个字符串的时候,不用截取子字符串,再操作。
// 先计算出第一个子字符串的需要信息,然后遍历,尾部多一个就+1,头部多一个,不操作,双索引操作。
/**
* @param {string} s
* @param {number} k
* @return {number}
*/
var maxVowels = function(s, k) {
let len = s.length;
let l = 0, r = k-1;
let tmp = 0, ans = 0;
let t = ['a','e','i','o','u'];
for(let i=l; i<=r; i++){
if(t.includes(s[i])){
tmp++
}
}
ans =Math.max(ans, tmp);
// 必须循环到len-1,因为是从k-1开始的
while(r!=len-1){
r++
if(t.includes(s[r])){
tmp++
}
if(t.includes(s[l])){
tmp--
}
l++;
ans = Math.max(ans, tmp);
if(ans === k) return k
}
return ans
};
给你一棵二叉树,每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的,当它满足:路径经过的所有节点值的排列中,存在一个回文序列。
请你返回从根到叶子节点的所有路径中 伪回文 路径的数目。
二叉树中的伪回文路径
示例 1:


输入:root = [2,3,1,3,1,null,1] 输出:2 解释:上图为给定的二叉树。总共有 3 条从根到叶子的路径:红色路径 [2,3,3] ,绿色路径 [2,1,1] 和路径 [2,3,1] 。 在这些路径中,只有红色和绿色的路径是伪回文路径,因为红色路径 [2,3,3] 存在回文排列 [3,2,3] ,绿色路径 [2,1,1] 存在回文排列 [1,2,1] 。
示例 2:


输入:root = [2,1,1,1,3,null,null,null,null,null,1]
输出:1
解释:上图为给定二叉树。总共有 3 条从根到叶子的路径:绿色路径 [2,1,1] ,路径 [2,1,3,1] 和路径 [2,1] 。
这些路径中只有绿色路径是伪回文路径,因为 [2,1,1] 存在回文排列 [1,2,1] 。
示例 3:
输入:root = [9] 输出:1
提示:
- 给定二叉树的节点数目在
1到10^5之间。 - 节点值在
1到9之间。
// 到达底部,拿到这条路径上的所有节点,然后判断是否是回文,但是这个路径总是深度优先遍历的顺序,所有路径都一样,然后就不知怎么写了
var pseudoPalindromicPaths = function(root) {
// let all = [];
// const dfs=(node, arr)=>{
// if(!node){
// return;
// }
// arr.push(node.val);
// // if(!node.left && !node.right){
// // all.push(arr);
// // return
// // }
// if(node.left) {
// dfs(node.left, arr)
// }
// if(node.right) {
// dfs(node.right, arr)
// }
// }
}
var pseudoPalindromicPaths = function(root) {
const check=(cnt)=> {
let odd = 0;
for(let i = 0; i <= 9; i++) {
if(cnt[i]&1) {
odd++;
}
}
if(odd <= 1) {
return 1;
}
return 0;
}
const dfs=(root, cnt)=> {
if(!root) {
return 0;
}
cnt[root.val] ++;
if(!root.left && !root.right) {
// 奇数个数<=1才是伪回文
let anw = check(cnt);
// 回溯减去当前值
cnt[root.val]--;
console.log('anw: ',anw)
return anw;
}
let anw = 0;
if(root.left) {
anw += dfs(root.left, cnt);
}
if(root.right) {
anw += dfs(root.right, cnt);
}
// 回溯减去当前值
cnt[root.val] --;
console.log('return anw: ',anw)
return anw;
}
let cnt = new Array(10).fill(0);
return dfs(root, cnt);
}
class Solution {
int ans=0;
public int pseudoPalindromicPaths (TreeNode root) {
if(root==null) return 0;
helper(root,0);
return ans;
}
void helper(TreeNode node,int temp){
temp^=(1<<node.val);//node节点的val为几就左移几位
if(node.left==null&&node.right==null){//判断是否叶子节点
if(temp==0||(temp&(temp-1))==0){//判断是否为伪回文
ans++;
}
}
if(node.left!=null) helper(node.left,temp);
if(node.right!=null) helper(node.right,temp);
return;
}
}
作者:rational-irrationality 链接:https://leetcode-cn.com/problems/pseudo-palindromic-paths-in-a-binary-tree/solution/java-dfs-shuang-bai-by-rational-irrationality/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

浙公网安备 33010602011771号