使用哈夫曼编码,从下往上来找,找最小的两个数,加起来扔进数组中,再从数组中找到最小的两个数,最后加起来的总和就是最小花费。
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));
}
}
- 暴力递归:因为会产生很多的重复计算,所以会造成时间复杂度很高。若把计算出的结果能保存起来,就会好很多
- 暴力递归改成动态规划
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));
}
}