第二十一天
1763 最长的美好子串
当一个字符串s
包含的每一种字母的大写和小写形式 同时 出现在s
中,就称这个字符串 s
是 美好 字符串。比方说,"abABB"
是美好字符串,因为'A'
和 'a'
同时出现了,且 'B'
和'b'
也同时出现了。然而,"abA"
不是美好字符串因为'b'
出现了,而 'B'
没有出现。
给你一个字符串s
,请你返回s
最长的 美好子字符串 。如果有多个答案,请你返回 最早 出现的一个。如果不存在美好子字符串,请你返回一个空字符串。
方法
遍历字符的开始位置,每次从字符串的开始位置往后扫。使用二进制对美好字符串的判断进行优化,定义两个变量lowerCase
和upperCase
,前者用于记录出现的小写字母,后者用于记录出现的大写字母。记录过程使用二进制移位来实现,比如遇到了字符y
,该字符是字母表中的第25
个字符,因此我们将lowerCase
的二进制表示从低到高的第25
位置为1
即可,大写字母同理,这样一来判断一个字符串是否是美好字符串就变成了判断这两个变量的值是否相同即可。
class Solution {
public String longestNiceSubstring(String s) {
int startPos = 0;
int length = 0;
for (int start = 0; start < s.length(); ++start){
int lowerCase = 0;
int upperCase = 0;
for (int i = start; i < s.length(); ++i){
if (Character.isLowerCase(s.charAt(i))) lowerCase |= 1 << (s.charAt(i) - 'a');
else upperCase |= 1 << (s.charAt(i) - 'A');
if (lowerCase == upperCase){
if (i - start + 1 > length){
startPos = start;
length = i - start + 1;
}
}
}
}
return s.substring(startPos, startPos + length);
}
}
117 填充每个节点的下一个右侧节点指针 II
给定一个二叉树
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next
指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将next
指针设置为 NULL
。
初始状态下,所有next
指针都被设置为NULL
。
进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
方法
将二叉树的每一层看作是一个链表,如果过已经直到了上层的链表,那么很容易通过树结构得到下层的链表中的所有节点,将这些节点全部连接起来即可。
class Solution {
public Node connect(Node root) {
if (root == null) return root;
Node head = root;
while (head != null){
Node p = head;
Node pre = null;
while (p != null){
if (p.left != null && p.right != null){
if (pre != null) pre.next = p.left;
p.left.next = p.right;
pre = p.right;
}
else if (p.left != null) {
if (pre != null) pre.next = p.left;
pre = p.left;
}
else if (p.right != null) {
if (pre != null) pre.next = p.right;
pre = p.right;
}
p = p.next;
}
while (head != null){
if (head.left != null){
head = head.left;
break;
}
else if (head.right != null){
head = head.right;
break;
}
head = head.next;
}
}
return root;
}
}
572 另一颗子树
给你两棵二叉树root
和 subRoot
。检验 root
中是否包含和 subRoot
具有相同结构和节点值的子树。如果存在,返回true
;否则,返回 false
。
二叉树 tree
的一棵子树包括 tree
的某个节点和这个节点的所有后代节点。tree
也可以看做它自身的一棵子树。
方法 Hash散列方法
为每一棵二叉树生成一个唯一的hash
值,使用hash
值比较两个树相等,如果不相等,递归的去访问左右子树是否和要求的子树是否相等。
class Solution {
public static int subHash;
public static int getHash(TreeNode root, int layer){
int res = 0;
if (root != null){
int val = root.val;
if (val == 0) val = 11;
res += val * layer * 154 + getHash(root.left, layer + 11) + getHash(root.right, layer + 1001);
}
return res;
}
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
subHash = getHash(subRoot, 1);
return judge(root);
}
public boolean judge(TreeNode root) {
if (root == null) return false;
if (getHash(root, 1) == subHash) return true;
return judge(root.left) || judge(root.right);
}
}