545. Boundary of Binary Tree
题目:Recursion
- 给定一个树形结构,返回 [ 根节点,左边界(为一个list),从左到右的所有叶子结点,及反序右边界] 的concatenation
- 左边界中的节点包括:
-
- 根节点的左儿子。若根节点无左儿子,左边界中无节点
-
- 左边界中节点的左儿子,或无左儿子的节点的右儿子
-
- 须删掉最左的叶节点。* 由于左边界为沿着一棵树的最左走到底,遇到的第一个也是唯一一个叶节点即为最左的叶节点
- 右边界定义同理
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def boundaryOfBinaryTree(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
def findLeaves(node):
if (not node.left and not node.right):
if (node!=root):
res.append(node.val)
return
if (node.left):
findLeaves(node.left)
if (node.right):
findLeaves(node.right)
def findLeftB(res, node):
if (node==root and not root.left):
return
if (node!=root):
res.append(node.val)
if (not node.left and not node.right):
res.pop() #remove leftmost leaf
return
if (node.left):
findLeftB(res, node.left)
elif (node.right):
findLeftB(res, node.right)
def findRightB(res, node):
if (node==root and not root.right):
return
if (node!=root):
res.append(node.val)
if (not node.left and not node.right):
res.pop()
return
if (node.right):
findRightB(res, node.right)
elif (node.left):
findRightB(res, node.left)
res = [root.val]
findLeftB(res, root)
findLeaves(root)
idx = len(res)
findRightB(res, root)
a = res[idx:]
a.reverse()
res = res[0:idx]+a
return res
915. Partition Array into Disjoint Intervals
题目大意:给定数组nums = [5,0,3,8,6],划分成两个subarray: left & right使得max{left} <= min{right}
思路: 顺序记录leftmax,倒序记录minright,从左到右找到第一个满足max{left} <= min{right}的划分点
class Solution {
public int partitionDisjoint(int[] nums) {
int N = nums.length;
int[] maxL = new int[N];
int[] minR = new int[N];
maxL[0] = nums[0];
for (int i=1; i<N; i++) {
maxL[i] = Math.max(maxL[i-1], nums[i]);
//System.out.println(maxL[i]);
}
minR[N-1] = nums[N-1];
for (int i=N-2; i>=0; i--) {
minR[i] = Math.min(minR[i+1], nums[i]);
//System.out.println(minR[i]);
}
int idx = 0;
while (idx<N && maxL[idx]>minR[idx+1]) {
idx++;
}
return idx+1;
}
}
1647. Minimum Deletions to Make Character Frequencies Unique
先数频次,对频次排序,hashset记录distinct frequency,若频次出现重复则尝试删除,* 忽略频次0的重复出现
class Solution {
public int minDeletions(String s) {
int[] count = new int[26];
char[] chars = s.toCharArray();
for (char c : chars) {
count[c-'a']++;
}
Arrays.sort(count);
int idx = 0;
while (count[idx]==0) idx++;
int ans = 0;
HashSet<Integer> freq =new HashSet<Integer>();
while (idx<26) {
int t = count[idx];
if (!freq.contains(t)) {
freq.add(t);
} else {
while (t>0) {
if (!freq.contains(t)) break;
t--;
}
if (t!=0) freq.add(t);
ans += count[idx] - t;
//System.out.println(ans);
}
idx++;
}
return ans;
}
}
- 题目描述
-
- 从C++代码中删除注释,多行"/* … */",单行"//"。注意:
-
- “/* … */” 中的 “//” 不起作用 ,同理 同一行中"//" 后的 “/*” 不起作用
-
- 特殊情况!!"/*/" 作为多行注释的开始并不能结束多行注释,但作为多行注释的结尾可以结束多行注释(故只能在开始时跳过"/*/", 而不能在判断closing的时候处理该coner case)
-
- 空字符串不应被加入答案
-
- 删掉多行注释的开头行和结束行的内容应该被合并, 即[“a/.", "…/b”]需要被合并为[“ab”]而非 [“a”, “b”]
- 最好使用while循环而非for循环来控制index,因为需要连续跳过注释的内容
class Solution {
public List<String> removeComments(String[] source) {
List<String> ans = new ArrayList<>();
int flag1 = 0, flag2=0; // flag1 for /*, flag2 for //, 1 = exist
StringBuilder sb = new StringBuilder();
for (String s : source) {
char[] chars = s.toCharArray();
int N = chars.length;
int i=0;
while (i<N) {
if (flag1 == 1) { // in /*
if (chars[i]=='*' && i+1<N && chars[i+1]=='/') {
flag1 = 0;
i+=2;
continue;
}
} else {//not in /*
if (chars[i]=='/') {
if (i+1<N && chars[i+1]=='*') { //start an /*
flag1 = 1;
i+=2;
if (i<N && chars[i]=='/') i++; //corner case /*/
continue;
}
if (i+1<N && chars[i+1]=='/') { //start an // : jump to the end of the line
i=N;
continue;
}
}
}
if (flag1==0) {
sb.append(chars[i]);
}
i++;
}
String str = sb.toString();
if (!str.equals("") && flag1==0) {
ans.add(str); //only add and refresh when block comment is closed
sb = new StringBuilder();
}
//System.out.println(str);
}
return ans;
}
}