左神b站 P8 贪心法、暴力递归以及动态规划

在这里插入图片描述
使用哈夫曼编码,从下往上来找,找最小的两个数,加起来扔进数组中,再从数组中找到最小的两个数,最后加起来的总和就是最小花费。

import java.util.PriorityQueue;

public class MinCost {
	//求割金条的最小代价
	public int mincost(int[] nums) {
		PriorityQueue<Integer> pq = new PriorityQueue<>();//默认是按照自然顺序排的,可以放入比较器
		int cost = 0;
		int size = 0;
		for(int i = 0;i < nums.length;i++) {
			pq.add(nums[i]);
		}
		while(pq.size() > 1) {
			cost = pq.poll() + pq.poll();
			size += cost;
			pq.add(cost);
		}
		return size;
	}
	
	public static void main(String[] args) {
		MinCost mc = new MinCost();
		int[] nums = {6,7,8,9};
		System.out.println(mc.mincost(nums));
	}
}

在这里插入图片描述
一次只能做一个项目,最多总共可以做K个。按照花费建立小根堆,把满足初金要求的项目按照项目放在大根堆中,大根堆是按照收益。当完成一个项目以后,启动资金增加,继续把小根堆中满足要求的放到大根堆中,以此类推。
在这里插入图片描述

package interview;
import java.util.Comparator;
import java.util.PriorityQueue;

public class MostMoney {
	public static class Node{
		int p;
		int c;
		public Node(int p,int c) {
			this.p = p;
			this.c = c;
		}
	}
	public static class AscComparator implements Comparator<Node>{
		@Override
		public int compare(Node i,Node j) {
			return i.c - j.c;
		}
	}
	public static class DescComparator implements Comparator<Node>{
		@Override
		public int compare(Node i,Node j) {
			return i.p - j.p;
		}
	}

	
	public int mostmoney(int[] costs,int[] profits,int k,int m) {
		//按照花费的大小建立一个小根堆,把大家都放进去,大根堆里只放小于项目启动资金m的项目,按照收益建立大根堆
		//小根堆
		PriorityQueue<Node> pqcost = new PriorityQueue<>(new AscComparator());
		//大根堆	
		PriorityQueue<Node> pqprofit = new PriorityQueue<>(new DescComparator());	
		Node[] nd = new Node[costs.length]; 
		for(int i = 0;i < costs.length;i++) {
			nd[i] = new Node(profits[i],costs[i]);
			pqcost.add(nd[i]);
			if(nd[i].c < m) {
				pqprofit.add(nd[i]);
			}
		}
		int sum = m;
		while(!pqprofit.isEmpty() && k > 0) {
			sum += pqprofit.poll().p;
			while(!pqcost.isEmpty() && pqcost.peek().c <= sum) {
				pqprofit.add(pqcost.poll());
			}
			k--; 
		}
		return sum;
		
	}	
}

在这里插入图片描述
思路:先找到最早结束的会议,然后排除掉和最早结束会议的时间有冲突的会议。这样可以找到最多的会议
在这里插入图片描述

package class_07;

import java.util.Arrays;
import java.util.Comparator;

public class Code_06_BestArrange {

	public static class Program {
		public int start;
		public int end;

		public Program(int start, int end) {
			this.start = start;
			this.end = end;
		}
	}

	public static class ProgramComparator implements Comparator<Program> {

		@Override
		public int compare(Program o1, Program o2) {
			return o1.end - o2.end;
		}

	}

	public static int bestArrange(Program[] programs, int start) {
		Arrays.sort(programs, new ProgramComparator());
		int result = 0;
		for (int i = 0; i < programs.length; i++) {
			if (start <= programs[i].start) {
				result++;
				start = programs[i].end;
			}
		}
		return result;
	}

	public static void main(String[] args) {

	}

}

总结:贪心策略靠累计

汉诺塔
在这里插入图片描述

package interview;

public class Hanoi {
	//汉诺塔问题
	//N : 1 ~ N
	public static void hanoi(int N,String from,String to,String help) {
		if(N == 1) {
			System.out.println("Move 1 from "+ from +" to " + to);
		}else {
			hanoi(N-1,from,help,to);
			System.out.println("Move " + N + " from " + from + " to " + to);
			hanoi(N-1,help,to,from);
		}
	}
	public static void main(String[] args) {
		int n = 3;
		hanoi(3,"左","右","中");
	}
}

在这里插入图片描述

package interview;

public class StringZuHe {
	//打印一个字符串的所有子序列
	public static void printstr(String str) {
		char[] stra = str.toCharArray();
		printstr("",stra,0);
	}
	public static void printstr(String str,char[] stra,int index) {
		if(index == stra.length) {
			System.out.println(str);//这个println的位置是关键哟
			return;
		}
		printstr(str,stra,index+1);
		printstr(str+stra[index++],stra,index);
	}
	public static void main(String[] args) {
		printstr("abc");
	}
}

在这里插入图片描述

package class_08;

import java.util.HashSet;

public class Code_04_Print_All_Permutations {
	//打印所有的排列,包含重复的
	public static void printAllPermutations1(String str) {
		char[] chs = str.toCharArray();
		process1(chs, 0);
	}

	public static void process1(char[] chs, int i) {
		if (i == chs.length) {
			System.out.println(String.valueOf(chs));
		}
		for (int j = i; j < chs.length; j++) {
			swap(chs, i, j);
			process1(chs, i + 1);
		}
	}
	//打印所有的排列,不重复的
	public static void printAllPermutations2(String str) {
		char[] chs = str.toCharArray();
		process2(chs, 0);
	}

	public static void process2(char[] chs, int i) {
		if (i == chs.length) {
			System.out.println(String.valueOf(chs));
		}
		HashSet<Character> set = new HashSet<>();
		for (int j = i; j < chs.length; j++) {
			if (!set.contains(chs[j])) {
				set.add(chs[j]);
				swap(chs, i, j);
				process2(chs, i + 1);
				//swap(chs, i, j);
			}
		}
	}

	public static void swap(char[] chs, int i, int j) {
		char tmp = chs[i];
		chs[i] = chs[j];
		chs[j] = tmp;
	}

	public static void main(String[] args) {
		String test1 = "abc";
		printAllPermutations1(test1);
		System.out.println("======");
		printAllPermutations2(test1);
		System.out.println("======");

		String test2 = "acc";
		printAllPermutations1(test2);
		System.out.println("======");
		printAllPermutations2(test2);
		System.out.println("======");
	}
}

在这里插入图片描述
思路:
在这里插入图片描述

package interview;

public class cow {
	public static int cownums(int N) {
		if(N < 1)
			return 0;
		if(N == 1 || N == 2 || N == 3) 
			return N;
		return cownums(N-1)+cownums(N-3);
	}
	
	public static void main(String[] args) {
		System.out.println(cownums(4));
	}
}

在这里插入图片描述

  1. 暴力递归:因为会产生很多的重复计算,所以会造成时间复杂度很高。若把计算出的结果能保存起来,就会好很多在这里插入图片描述
  2. 暴力递归改成动态规划
package class_08;

public class Code_07_MinPath {

	public static int minPath1(int[][] matrix) {
		return process1(matrix, matrix.length - 1, matrix[0].length - 1);
	}

	public static int process1(int[][] matrix, int i, int j) {
		int res = matrix[i][j];
		if (i == 0 && j == 0) {
			return res;
		}
		if (i == 0 && j != 0) {
			return res + process1(matrix, i, j - 1);
		}
		if (i != 0 && j == 0) {
			return res + process1(matrix, i - 1, j);
		}
		return res + Math.min(process1(matrix, i, j - 1), process1(matrix, i - 1, j));
	}
	//动态规划方法
	public static int minPath2(int[][] m) {
		if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
			return 0;
		}
		int row = m.length;
		int col = m[0].length;
		int[][] dp = new int[row][col];
		dp[0][0] = m[0][0];
		for (int i = 1; i < row; i++) {
			dp[i][0] = dp[i - 1][0] + m[i][0];
		}
		for (int j = 1; j < col; j++) {
			dp[0][j] = dp[0][j - 1] + m[0][j];
		}
		for (int i = 1; i < row; i++) {
			for (int j = 1; j < col; j++) {
				dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + m[i][j];
			}
		}
		return dp[row - 1][col - 1];
	}

	// for test
	public static int[][] generateRandomMatrix(int rowSize, int colSize) {
		if (rowSize < 0 || colSize < 0) {
			return null;
		}
		int[][] result = new int[rowSize][colSize];
		for (int i = 0; i != result.length; i++) {
			for (int j = 0; j != result[0].length; j++) {
				result[i][j] = (int) (Math.random() * 10);
			}
		}
		return result;
	}

	public static void main(String[] args) {
		int[][] m = { { 1, 3, 5, 9 }, { 8, 1, 3, 4 }, { 5, 0, 6, 1 }, { 8, 8, 4, 0 } };
		System.out.println(minPath1(m));
		System.out.println(minPath2(m));

		m = generateRandomMatrix(6, 7);
		System.out.println(minPath1(m));
		System.out.println(minPath2(m));
	}
}

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值