AB入栈;f(2) = f(0)*f(1)+f(1)*f(0)=2
(()) -----()()
ABCD
按照“第一个入栈的元素,在出栈序列中的位置”作为分类手段。
A在第一个那么就是()入出,额外的f(0)
那么此时剩下的就是f(3)
第二个出,(())那么剩下的就是f(2)
第三个-((()))or( ( ) ( ) ) 也就是f(2)除开必须第三个的A,剩下的是f(1)
所以就是f(0)Af(3)-f(1)Af(2)-f(2)Af(1)-f(3)Af(0)
这就是所有出栈排列
注意先用4n-2乘以f(n-1)再除以,不然损失精度
有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少种方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈):
https://leetcode.cn/problems/special-binary-string/
class Solution {
public String makeLargestSpecial(String s) {
if (s.length() <= 2) {
return s;
}
int cnt = 0, left = 0;
List<String> subs = new ArrayList<String>();
for (int i = 0; i < s.length(); ++i) {
if (s.charAt(i) == '1') {
++cnt;
} else {
--cnt;
if (cnt == 0) {
subs.add("1" + makeLargestSpecial(s.substring(left + 1, i)) + "0");
left = i + 1;
}
}
}
Collections.sort(subs, (a, b) -> b.compareTo(a));
StringBuilder ans = new StringBuilder();
for (String sub : subs) {
ans.append(sub);
}
return ans.toString();
}
}
class Solution {
public String largestNumber(int[] nums) {
PriorityQueue<String> heap = new PriorityQueue<>((x, y) -> (y + x).compareTo(x + y));
for(int x: nums) heap.offer(String.valueOf(x));
String res = "";
while(heap.size() > 0) res += heap.poll();
if(res.charAt(0) == '0') return "0";
return res;
}
}
PriorityQueue<Integer> heap3 = new PriorityQueue<>(Comparator.reverseOrder());
https://www.jianshu.com/p/81e5c3e88fc6
因为最小堆里面字符串顺序,3是小于30但是大于10,但是我们想要的是330而不是303
同理3-31, 3-32,
也就是字典顺序不行了,那么其实反正目的是比较任意的,直接拼在一起比较
字符串:(x+y)->(y+x).compareTo(x+y)
x,y---3,32, 现在323<332比较--> x<y,3<32
所以顺序是3,32,31,30,交换x,y顺序就变成最小堆了,
这样子排序然后拼接在一起就是最大数了。
class Solution {
public String largestNumber(int[] nums) {
Queue<String> pq = new PriorityQueue<>((x,y)->((y+x).compareTo(x+y)));
for(int each: nums){
pq.offer(String.valueOf(each));
}
StringBuffer str = new StringBuffer();
while(!pq.isEmpty()){
str.append(pq.poll());
}
if(str.charAt(0)=='0') return "0";
return str.toString();
}
}
注意{0,0},原数据和目标数据都不存在00,最多0,
Collections.sort(list,(x,y)->x.compareTo(y));
//
list.sort((x,y)->x.compareTo(y));
两种调用排序
1 10 1100 0---这个是不能拆的最小的特殊的序列,
如何判断是否是不可以分割的,那就是()一个完整的括号,所以就是数1和0,一旦是抵消就是不可以分割的
比如10,1100,110100
因此第一步就是将一个字符串分割成这样的子串,然后按照字典顺序排序即可
然后每个字串自己本身也是除开首尾,内部的
101100---这样的根本不满足最小分割,因为直接可以10,1100,因此也就是说,
2: 10
4,1010不会出现,最多1100
6,10 10 10,10 1100,1100 10统统不行,可以再分,110100,111000就可以
110100不可以再分,意味着第二也必须是1,那么因为首位必须是一对10,那么除开10,还剩1010,或者1100,那么如果是1010,最后就是分成10,10,如果是1100就是分成1-10-0
遇到1 count++,遇到0 count--
List<String> subs = new ArrayList<>();
int left=0,count=0;
for(int i=0;i<str.length();++i){
if(str.charAt(i)==1){
++count;
}else{
--count;
if(count==0){
subs.add("1"+makeLargestSpecial(str.substring(left+1,i)+"0");
left = i+1;
}
}
}
substring没有大写,且前闭后开
这样子就完成了所有分割,然后排序并且结合
Collections.sort(subs,(x,y)->y.compareTo(x));
StringBuffer ans = new StringBuffer();
for(String each: subs){
ans.append(each);
}
return ans.toString();
StringBuffer 需要转换成String
递归的初始条件就是10的时候以及110100---第一步分成10变成1-“”-0,也就是空集
所以
if(str.length()<=2){
return str;
}
subs.sort((x,y)->y.compareTo(x));
StringBuffer ans = new StringBuffer();
subs.forEach((each)->{
ans.append(each);
});
return ans.toString();
sort有两种方式调用
forEach函数也可以直接使用;