题1:给定一个由字符串组成的数组strs,必须把所有字符串拼接起来,返回所有可能的拼接结果中,字典序最小的结果
补充:
字典序:ASCII码,看成数字比大小
1)“abc”<“bcd” 2)"abcd"<"b"(b会补成b000)
public static class MyComparator implements Comparator<String>{
public int compare(String a,String b){
return (a+b).compareTo(b+a);
}
}
public static String lowestString2(String[] strs){
if(strs==null || strs.length==0){
return "";
}
Arrays.sort(strs,new MyComparator);
String res="";
for(int i=0;i<strs.length;i++){
res+=strs[i];
}
return res;
}
暴力解:
public static String[] removeIndexString(String[] arr,int index){
int N=arr.length;
String[] ans=new String[N-1];
int ansIndex=0;
for(int i=0;i<N;i++){
if(i!=index){
ans[ansIndex++]=arr[i];
}
}
return ans;
}
//strs中所有字符串全排列,返回所有可能结果
public static TreeSet<String> process(String[] strs){
TreeSet<String> ans=new TreeSet<>();
if(strs.length==0){
ans.add("");
return ans;
}
for(int i=0;i<strs.length;i++){
String first=strs[i];
String[] nexts=removeIndexString(strs,i);
TreeSet<String> next=process(nexts);
for(String cur:next){
ans.add(first+cur);
}
}
return ans;
}
public static String lowestString1(String[] strs){
if(strs==null || strs.length==0){
return "";
}
TreeSet<String> ans=process(strs);
return ans.size()==0?"":ans.first();
}
题2:一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。给你每一个项目开始的时间和结束的时间,你来安排宣讲的日程,要求会议室进行的宣讲的场次最多。返回最多的宣讲场次。
会议数据结构
public static class Program {
public int start;
public int end;
public Program(int start, int end) {
this.start = start;
this.end = end;
}
}
贪心解:
//会议的开始时间和结束时间,都是数值,不会<0
public static int bestArrange2(Program[] programs){
Arrays.sort(programs,new ProgramComparator());
int timeLine=0;
int result=0;
//依次遍历每一个会议,结束时间早的会议先遍历
for(int i=0;i<programs.length;i++){
if(timeLine<=programs[i].start){
result++;
timeLine=programs[i].end;
}
}
return result;
}
public static class ProgramComparator implements Comparator<Program>{
public int compare(Program o1,Program o2){
return o1.end-o2.end;
}
}
暴力解:
//会议的开始时间和结束时间,都是数值,不会<0
public static int bestArrange1(Program[] programs){
if(programs==null || programs.length==0){
return 0;
}
return process(programs,0,0);
}
//还剩的会议都放在programs里
//done之前已经安排了多少会议,数量
//timeLine目前来到的时间点是什么
//返回能安排的最多会议数量
public static int process(Program[] programs,int done,int timeLine){
if(programs.length==0){
return done;
}
int max=done;//还剩下会议
for(int i=0;i<programs.length;i++){
if(programs[i].start>=timeLine){
Program[] next=copyButExcept(programs,i);
max=Math.max(max,process(next,done+1,programs[i].end));
}
}
return max;
}
public static Program[] copyButExcept(Program[] programs,int i){
Program[] ans=new Program[programs.length-1];
int index=0;
for(int k=0;k<programs.length;k++){
if(k!=i){
ans[index++]=programs[k];
}
}
return ans;
}
题3:
读题示意图:
解法示意图:
public static int lessMoney2(int[] arr){
//小根堆
PriorityQueue<Integer> pQ=new PriorityQueue<>();
for(int i=0;i<arr.length;i++){
pQ.add(arr[i]);
}
int sum=0;
int cur=0;
while(pQ.size()>1){
cur=pQ.poll()+pQ.poll();//画圈的数加起来
sum+=cur;
pQ.add(cur);
}
return sum;
}
暴力解:
// 纯暴力!
public static int lessMoney1(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
return process(arr, 0);
}
// 等待合并的数都在arr里,pre之前的合并行为产生了多少总代价
// arr中只剩一个数字的时候,停止合并,返回最小的总代价
public static int process(int[] arr, int pre) {
if (arr.length == 1) {
return pre;
}
int ans = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
ans = Math.min(ans, process(copyAndMergeTwo(arr, i, j), pre + arr[i] + arr[j]));
}
}
return ans;
}
public static int[] copyAndMergeTwo(int[] arr, int i, int j) {
int[] ans = new int[arr.length - 1];
int ansi = 0;
for (int arri = 0; arri < arr.length; arri++) {
if (arri != i && arri != j) {
ans[ansi++] = arr[arri];
}
}
ans[ansi] = arr[i] + arr[j];
return ans;
}
题4:
//最多k个项目,w初始资金
//返回最终最大的资金
public static int findMaximizedCapital(int k,int w,int[] Profits,int[] Capital){
PriorityQueue<Program> minCostQ=new PriorityQueue<>(new MinCostComparator());
PriorityQueue<Program> maxProfitQ=new PriorityQueue<>(new MaxProfitComparator());
for(int i=0;i<Profits.length;i++){
minCostQ.add(new Program(Profits[i],Capital[i]));
}
for(int i=0;i<k;i++){
while(!minCostQ.isEmpty()&&minCostQ.peek().c<=w){
maxProfitQ.add(minCostQ.poll());
}
if(maxProfitQ.isEmpty()){
return w;
}
w+=maxProfitQ.poll().p;
}
return w;
}
public static class Program {
public int p;
public int c;
public Program(int p, int c) {
this.p = p;
this.c = c;
}
}
public static class MinCostComparator implements Comparator<Program> {
@Override
public int compare(Program o1, Program o2) {
return o1.c - o2.c;
}
}
public static class MaxProfitComparator implements Comparator<Program> {
@Override
public int compare(Program o1, Program o2) {
return o2.p - o1.p;
}
}
题5:
public static int minLight2(String road) {
char[] str = road.toCharArray();
int i = 0;
int light = 0;
while (i < str.length) {
if (str[i] == 'X') {
i++;
} else {
light++;
if (i + 1 == str.length) {
break;
} else { // 有i位置 i+ 1 X .
if (str[i + 1] == 'X') {
i = i + 2;
} else {
i = i + 3;
}
}
}
}
return light;
}