小白学习贪心算法(java)

题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;
	}

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值