//贪心算法
public class Tanxing {
//会议最多举行多少场问题
public static class Program {
public int start;
public int 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 timePoint) {
//首先根据会议结束时间来升序排序
Arrays.sort(programs, new ProgramComparator());
int result = 0;
//从左往右依次遍历所有的会议
for (int i = 0; i < programs.length; i++) {
//如果会议开始时间大于当前时间则可以加入
if (timePoint <= programs[i].start) {
// 可加入会议数加一
result++;
// 当前时间变成当前会议结束时间
timePoint = programs[i].end;
}
}
return result;
}
//字符串组成最小字典序问题
public static class MyComparator implements Comparator<String> {
@Override
public int compare(String a, String b) {
return (a + b).compareTo(b + a);
}
}
public static String lowestString(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 int lessMoney(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 class MinComparator implements Comparator<Linkedlist.Node> {
@Override
public int compare(Linkedlist.Node o1, Linkedlist.Node o2) {
return o1.C - o2.C;
}
}
public static class MaxComparator implements Comparator<Linkedlist.Node> {
@Override
public int compare(Linkedlist.Node o1, Linkedlist.Node o2) {
return o2.P - o1.P;
}
}
public static int findMaximizedCaptital(int k, int w, int[] Prpfits, int[] Capital) {
PriorityQueue<Linkedlist.Node> minCostQ = new PriorityQueue<Linkedlist.Node>(new MinComparator());
PriorityQueue<Linkedlist.Node> maxProfiyQ = new PriorityQueue<Linkedlist.Node>(new MaxComparator());
//所有的项目扔到被锁池中,花费组织的小根堆
for (int i = 0; i < Prpfits.length; i++) {
minCostQ.add(new Linkedlist.Node(Prpfits[i], Capital[i]));
}
//进行k轮
for (int i = 0; i < 5; i++) {
//能力所及的项目全部都解锁
while (!minCostQ.isEmpty() && minCostQ.peek().C <= w) {
maxProfiyQ.add(minCostQ.poll());
}
if (maxProfiyQ.isEmpty()) {
return w;
}
w += maxProfiyQ.poll().P;
}
return w;
}
//动态获取中位数
public static void getzhoweishup(int[] arr) {
PriorityQueue<Integer> biggestQ = new PriorityQueue<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});//大根堆
PriorityQueue<Integer> smartgestQ = new PriorityQueue<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});//小根堆
biggestQ.add(arr[0]);//首先第一个数加入大根堆
for (int i = 1; i < arr.length; i++) {
//每次加入堆的数之前先跟大根堆的堆顶进行比较 如果大于堆顶就加入到小根堆中,如果小于堆顶就加入到大根堆中 ,如果大根堆或者小根堆里面的元素个数比对方大2个那么就把堆顶给对方
if (arr[i] > biggestQ.peek()) {
smartgestQ.add(arr[i]);
} else {
biggestQ.add(arr[i]);
}
if (biggestQ.size() - smartgestQ.size() == 2) {
smartgestQ.add(biggestQ.poll());
} else if (smartgestQ.size() - biggestQ.size() == 2) {
biggestQ.add(smartgestQ.poll());
}
//此时数组中的数都在大根堆和小根堆里面了 然后比较大根堆和小根堆的size 如果相等就栈顶相加除以二 如果不相等就弹出size大的那一个的栈顶
if (biggestQ.size() > smartgestQ.size()) {
System.out.println("中位数为:" + biggestQ.peek());
} else if (biggestQ.size() < smartgestQ.size()) {
System.out.println("中位数为:" + smartgestQ.peek());
}
System.out.println("中位数为:" + ((biggestQ.peek() + smartgestQ.peek()) >> 1));
}
}
//n皇后问题
public static int num1(int n) {
if (n < 1) {
return 0;
}
int[] record = new int[n]; //record[i]->i行的皇后,放在了第几列
return process1(0, record, n);
}
private static int process1(int i, int[] record, int n) {
if (i == n) {//终止行
return 1;
}
int res = 0;
for (int j = 0; j < n; j++) {
//record[i]表示第i行的皇后在第几列
//当前i行的皇后,放在j列,会不会和之前(0...i-1)的皇后,共行共列或者共斜线,
//如果是,认为无效
//如果不是,认为有效
if (isValid(record, i, j)) {
record[i] = j;
res += process1(i + 1, record, n);
}
}
return res;
}
private static boolean isValid(int[] record, int i, int j) {
for (int k = 0; k < i; k++) {//之前的某个k行的皇后
if (j == record[k] || Math.abs(record[k] - j) == Math.abs(i - k)) {
return false;
}
}
return true;
}
//请不要超过32皇后问题
public static int num2(int n) {
if (n < 1 | n > 32) {
return 0;
}
//例如你是9皇后 那么1左移9位然后-1 就变成了 1 1111 1111 limit不变的
int limit = n == 32 ? -1 : (1 << n) - 1;
return process2(limit, 0, 0, 0);
}
// limit 划定了问题的规模->固定
// colLim列的限制,1的位置不能放皇后,0的位置可以
// leftDiaLim 左斜线的限制,1的位置不能放皇后,0的位置可以
// rightDiaLim 右斜线的限制,1的位置不能放皇后,0的位置可以
public static int process2(
int limit,
int colLim,
int leftDialim,
int rightDiaLim) {
//什么时候列的限制变成了1 1111 1111 那么就说明填满了 就说明这个路线可行 返回1
if (colLim == limit) { // base case
return 1;
}
//所有候选皇后的位置,都在pos上
//(colLim | leftDiaLim | rightDialim) 总限制
//~(colLim | leftDiaLim | rightDialim) 右侧是有效的每个1是可以尝试放皇后的位置
//例如列限制是0001 那么左侧限制就是0010 右侧限制就是 0000 然后把三个或起来就变成了0011 然后取反就变成了1100 然后与上limit 就变成了 皇后可以填入的地方
int pos = limit & (~(colLim | leftDialim | rightDiaLim));
int mostRightOne = 0;
int res = 0;
while (pos != 0) {
//取出当前的最右边的可以填入皇后的点 然后填入皇后
mostRightOne = pos & (~pos + 1);
//pos当递归返回的时候就尝试下一条路线
pos = pos - mostRightOne;
res += process2(limit,
// 新的列限制
colLim | mostRightOne,
// 左斜线限制 每次向下递归的时候要左移
(leftDialim | mostRightOne) << 1,
// 右斜线限制 每次向下递归的时候要右移
(rightDiaLim | mostRightOne) >>> 1);
}
return res;
}
//暴力递归 汉罗塔问题
public static void process(int N, String 左, String 中, String 右) {
if (N == 1) {
System.out.println("Move " + N + " from " + 左 + " to " + 右);
} else {
process(N - 1, 左, 右, 中);//第一步:把1到n-1从from移动到help组上去
System.out.println("Move " + N + " from " + 左 + " to " + 右);
process(N - 1, 中, 左, 右);//第三步:把1到n-1从help上移动到to上去
}
}
public static void main(String[] args) {
// process(3,"左边","中间","右边");
int i = num2(9);
// System.out.println(i);
// Program p1 = new Program();
// Program p2 = new Program();
// Program p3 = new Program();
// Program p4 = new Program();
// Program p5 = new Program();
// Program p6 = new Program();
// p1.start =7;
// p1.end =9;
// p2.start =6;
// p2.end = 8;
// p3.start =9;
// p3.end =12;
// p4.start =15;
// p4.end =16;
// p5.start =13;
// p5.end =15;
// p6.start =14;
// p6.end =17;
// Program[] programs = {p1,p2,p3,p4,p5,p6};
// bestArrange(programs,6);
// String[] strs = {"ab","acd","abc","cda"};
// lowestString(strs);
// int[] prpfits = {2,4,7,9,6,3};
// getzhoweishup(prpfits);
// System.out.println((4+7)>>1);
// System.out.println(getzhoweishup);
// int[] capital = {1,2,2,5,3};
// int w = 1;
// int k = 4;
// int maximizedCaptital = findMaximizedCaptital(k, w, prpfits, capital);
// System.out.println(maximizedCaptital);
}
}
算法基础部分-贪心算法
最新推荐文章于 2024-07-24 20:44:05 发布