LeetCode 1609. 奇偶树 / 1078. Bigram 分词 / 825. 适龄的朋友(计数排序)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1609. 奇偶树 / 1078. Bigram 分词 / 825. 适龄的朋友(计数排序)相关的知识,希望对你有一定的参考价值。
1609. 奇偶树
2021.12.25 每日一题,圣诞快乐,考研顺利,今天没有圣诞树,但是有奇偶树
题目描述
如果一棵二叉树满足下述几个条件,则可以称为 奇偶树 :
二叉树根节点所在层下标为 0 ,根的子节点所在层下标为 1 ,根的孙节点所在层下标为 2 ,依此类推。
偶数下标 层上的所有节点的值都是 奇 整数,从左到右按顺序 严格递增
奇数下标 层上的所有节点的值都是 偶 整数,从左到右按顺序 严格递减
给你二叉树的根节点,如果二叉树为 奇偶树 ,则返回 true ,否则返回 false 。
示例 1:
输入:root = [1,10,4,3,null,7,9,12,8,6,null,null,2]
输出:true
解释:每一层的节点值分别是:
0 层:[1]
1 层:[10,4]
2 层:[3,7,9]
3 层:[12,8,6,2]
由于 0 层和 2 层上的节点值都是奇数且严格递增,而 1 层和 3 层上的节点值都是偶数且严格递减,因此这是一棵奇偶树。
示例 2:
输入:root = [5,4,2,3,3,7]
输出:false
解释:每一层的节点值分别是:
0 层:[5]
1 层:[4,2]
2 层:[3,3,7]
2 层上的节点值不满足严格递增的条件,所以这不是一棵奇偶树。
示例 3:
输入:root = [5,9,1,3,5,7]
输出:false
解释:1 层上的节点值应为偶数。
示例 4:
输入:root = [1]
输出:true
示例 5:
输入:root = [11,8,6,1,3,9,11,30,20,18,16,12,10,4,2,17]
输出:true
提示:
树中节点数在范围 [1, 10^5] 内
1 <= Node.val <= 10^6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/even-odd-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
层序遍历就行了
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode()
* TreeNode(int val) this.val = val;
* TreeNode(int val, TreeNode left, TreeNode right)
* this.val = val;
* this.left = left;
* this.right = right;
*
*
*/
class Solution
public boolean isEvenOddTree(TreeNode root)
//就是一个简单的层序遍历吧,想想
//层序遍历,因为每一层都是从左到右记录的,所以直接看是否递增递减和奇偶性就可以了
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int level = 0;
while(!queue.isEmpty())
int size = queue.size();
int last = -1;
while(size-- > 0)
TreeNode node = queue.poll();
int val = node.val;
//如果是奇数层
if((level & 1) == 1)
if((val & 1) == 1)
return false;
if(last != -1 && val >= last)
return false;
else
if((val & 1) == 0)
return false;
if(last != -1 && val <= last)
return false;
if(node.left != null)
queue.offer(node.left);
if(node.right != null)
queue.offer(node.right);
last = node.val;
level++;
return true;
1078. Bigram 分词
2021.12.26 每日一题
题目描述
给出第一个词 first 和第二个词 second,考虑在某些文本 text 中可能以 “first second third” 形式出现的情况,其中 second 紧随 first 出现,third 紧随 second 出现。
对于每种这样的情况,将第三个词 “third” 添加到答案中,并返回答案。
示例 1:
输入:text = “alice is a good girl she is a good student”, first = “a”, second = “good”
输出:[“girl”,“student”]
示例 2:
输入:text = “we will we will rock you”, first = “we”, second = “will”
输出:[“we”,“rock”]
提示:
1 <= text.length <= 1000
text 由小写英文字母和空格组成
text 中的所有单词之间都由 单个空格字符 分隔
1 <= first.length, second.length <= 10
first 和 second 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/occurrences-after-bigram
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
注意toArray()的用法
class Solution
public String[] findOcurrences(String text, String first, String second)
String[] txt = text.split(" ");
List<String> list = new ArrayList<>();
for(int i = 2; i < txt.length; i++)
if(txt[i - 2].equals(first) && txt[i - 1].equals(second))
list.add(txt[i]);
return list.toArray(new String[]);
825. 适龄的朋友
2021.12.27 每日一题
题目描述
在社交媒体网站上有 n 个用户。给你一个整数数组 ages ,其中 ages[i] 是第 i 个用户的年龄。
如果下述任意一个条件为真,那么用户 x 将不会向用户 y(x != y)发送好友请求:
age[y] <= 0.5 * age[x] + 7
age[y] > age[x]
age[y] > 100 && age[x] < 100
否则,x 将会向 y 发送一条好友请求。
注意,如果 x 向 y 发送一条好友请求,y 不必也向 x 发送一条好友请求。另外,用户不会向自己发送好友请求。
返回在该社交媒体网站上产生的好友请求总数。
示例 1:
输入:ages = [16,16]
输出:2
解释:2 人互发好友请求。
示例 2:
输入:ages = [16,17,18]
输出:2
解释:产生的好友请求为 17 -> 16 ,18 -> 17 。
示例 3:
输入:ages = [20,30,100,110,120]
输出:3
解释:产生的好友请求为 110 -> 100 ,120 -> 110 ,120 -> 100 。
提示:
n == ages.length
1 <= n <= 2 * 10^4
1 <= ages[i] <= 120
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/friends-of-appropriate-ages
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
第一时间被第三个条件给迷惑了,导致问题出了一大堆
发现问题后,又自然而然的认为两个相同的值是肯定要交流的,所以一直没发现错误
最终debug终于发现了问题,好不容易过了
其实应该写个双指针的
双指针更简单
class Solution
public int numFriendRequests(int[] ages)
//首先看条件,发现100以上和100以下是不会进行交流的,所以可以把年龄段分为100以上和100以下两个部分,且都包含100
//0.5 * age[x] + 7 < age[y] <= age[x]
//年龄大的给年龄小的发请求,小的不会给大的发
//想到一个思路,先排序,然后对于每一个年龄,查找可以发送请求的范围,找到这个值以后,通过下标来计算个数
//错了,第三个条件只是说小于100的不给大于100的发消息,但是大于100的可以给小于100的发
//然后再看第三个条件,x小于100,y大于100,第二个条件就给出不成立了,所以相当于恒成立............
//搞的我处理了半天这个条件
int n = ages.length;
Arrays.sort(ages);
int res = 0;
for(int i = 0; i < n;)
int left = 0;
int right = i - 1;
double range = 0.5 * ages[i] + 7;
while(left < right)
int mid = (right - left + 1) / 2 + left;
//如果满足条件的,那么就再往左边找第一个满足条件的
if((double)ages[mid] > range)
right = mid - 1;
else
left = mid;
//找相同值
int t = i + 1;
while(t < n && ages[t] == ages[i])
t++;
//如果left位置处的值满足条件
if((double)ages[left] > range)
int add = t - 1 - left;
res += (t - i) * add;
//如果不满足条件,那么只计算相同的
else
int add = t - left - 2;
if(add > 0 && (double)ages[i] > range)
res += (t - i) * add;
i = t;
return res;
双指针,但是竟然比二分要慢
class Solution
public int numFriendRequests(int[] ages)
//双指针果然更简单
int n = ages.length;
Arrays.sort(ages);
int left = 0, right = 0, ans = 0;
for (int age : ages)
if (age < 15)
continue;
while (ages[left] <= 0.5 * age + 7)
++left;
while (right + 1 < n && ages[right + 1] <= age)
++right;
ans += right - left;
return ans;
计数排序,统计每个年龄的人数,然后对于每一个年龄,计算满足条件的人的个数
用前缀和优化这个过程
class Solution
public int numFriendRequests(int[] ages)
//计数排序
//统计每个年龄的人数,然后对于每一个年龄,计算符合要求的人数
int[] num = new int[121];
for(int age : ages)
num[age]++;
int[] pre = new int[121];
for(int i = 1; i < 121; i++)
pre[i] = pre[i - 1] + num[i];
int ans = 0;
for(int i = 15; i < 121; i++)
int range = (int)(0.5 * i) + 7;
if(num[i] > 0)
ans += num[i] * (pre[i] - pre[range] - 1);
return ans;
以上是关于LeetCode 1609. 奇偶树 / 1078. Bigram 分词 / 825. 适龄的朋友(计数排序)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 1609 奇偶数[BFS] HERODING的LeetCode之路