2022年1月4日|5日|6日|7日|
生活随笔
收集整理的這篇文章主要介紹了
2022年1月4日|5日|6日|7日|
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
2022年1月第一周周記
圖算法
【思路】對(duì)于不同的圖算法,可能牽扯到不同方式的圖表達(dá)。所以選擇一個(gè)普適性強(qiáng)的圖結(jié)構(gòu)來(lái)表達(dá)所有圖算法基本圖結(jié)構(gòu)
package class06;import java.util.HashMap; import java.util.HashSet; import java.util.ArrayList;public class GraphGenerator {public static Graph createGraph(Integer[][] matrix) {// 數(shù)組記錄出發(fā)節(jié)點(diǎn)(編號(hào))和目的節(jié)點(diǎn)(編號(hào))以及權(quán)重Graph graph = new Graph();for (int i = 0; i < matrix.length; i++) {Integer weight = matrix[i][0];Integer from = matrix[i][1];Integer to = matrix[i][2];// 如果該邊的出入節(jié)點(diǎn)不在圖結(jié)構(gòu)中 ==> 添加// key:節(jié)點(diǎn)編號(hào)// value:以節(jié)點(diǎn)編號(hào)為值的節(jié)點(diǎn)if (!graph.nodes.containsKey(from)) {graph.nodes.put(from, new Node(from));}if (!graph.nodes.containsKey(to)) {graph.nodes.put(to, new Node(to));}// 以出發(fā)節(jié)點(diǎn)和目的節(jié)點(diǎn)構(gòu)造邊Node fromNode = graph.nodes.get(from);Node toNode = graph.nodes.get(to);Edge newEdge = new Edge(weight, fromNode, toNode);// 將目的節(jié)點(diǎn)添加至出發(fā)節(jié)點(diǎn)的連接數(shù)組中// 出發(fā)節(jié)點(diǎn)出度++// 目的節(jié)點(diǎn)入度++// 將上步構(gòu)造好的邊加入到節(jié)點(diǎn)的連接邊數(shù)組中fromNode.nexts.add(toNode);fromNode.out++;toNode.in++;fromNode.edges.add(newEdge);graph.edges.add(newEdge);}return graph;}public class Graph {public HashMap<Integer,Node> nodes;public HashSet<Edge> edges;public Graph() {nodes = new HashMap<>();edges = new HashSet<>();}}public class Edge {public int weight;public Node from;public Node to;public Edge(int weight, Node from, Node to) {this.weight = weight;this.from = from;this.to = to;}}public class Node {public int value;public int in;public int out;public ArrayList<Node> nexts;public ArrayList<Edge> edges;public Node(int value) {this.value = value;in = 0;out = 0;nexts = new ArrayList<>();edges = new ArrayList<>();}} }圖的寬度優(yōu)先遍歷
【思路】 1、利用隊(duì)列實(shí)現(xiàn) 2、從源節(jié)點(diǎn)開始依次按照寬度進(jìn)隊(duì)列,然后彈出 3、每彈出一個(gè)點(diǎn),把該點(diǎn)所有沒有進(jìn)過隊(duì)列的鄰接點(diǎn)放入隊(duì)列 4、直到隊(duì)列變空 ------------------------------- 圖和二叉樹的BFS區(qū)別在于,圖可能存在環(huán)結(jié)構(gòu),如果按照二叉樹的方式來(lái)遍歷會(huì)死循環(huán) package class06;import java.util.HashSet; import java.util.LinkedList; import java.util.Queue;public class Code01_BFS {// 從Node出發(fā),進(jìn)行BFSpublic static void bfs(Node node) {if (node == null) {return;}Queue<Node> queue = new LinkedList<>();HashSet<Node> map = new HashSet<>();queue.add(node);map.add(node);while (!queue.isEmpty()) {Node cur = queue.poll();System.out.println(cur.value);// 可以根據(jù)具體更改操作for (Node next : cur.nexts) {if (!map.contains(next)) {map.add(next);queue.add(next); }}}} }圖的深度優(yōu)先便利
【思路】 1、利用棧實(shí)現(xiàn) 2、從源節(jié)點(diǎn)開始把節(jié)點(diǎn)按照深度 3、每彈出一個(gè)點(diǎn),把該節(jié)點(diǎn)下一個(gè)沒有進(jìn)過棧的鄰接點(diǎn)放入棧 4、直到棧變空 package class06;import java.util.HashSet; import java.util.Stack;public class Code02_DFS {public static void dfs(Node node) {if (node == null) {return;}Stack<Node> stack = new Stack<>();HashSet<Node> set = new HashSet<>();stack.add(node);set.add(node);System.out.println(node.value); // 可以根據(jù)實(shí)際修改操作while (!stack.isEmpty()) {Node cur = stack.pop();for (Node next : cur.nexts) {if (!set.contains(next)) {stack.push(cur);stack.push(next);set.add(next);System.out.println(next.value);break;}}}} }拓?fù)渑判?/h3>
【適用范圍】要求為有向圖且有入度為0的節(jié)點(diǎn),并且沒有環(huán)
package class06;import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;public class Code03_TopologySort {// directed graph and no looppublic static List<Node> sortedTopology(Graph graph) {// key:某一個(gè)Node// Value:剩余的入度HashMap<Node, Integer> inMap = new HashMap<>();// 入度為0的點(diǎn)才能進(jìn)入這個(gè)隊(duì)列Queue<Node> zeroInQueue = new LinkedList<>();for (Node node : graph.nodes.values()) {inMap.put(node, node.in);if (node.in == 0) {zeroInQueue.add(node);}}// 拓?fù)渑判虻慕Y(jié)果,依次加入resultList<Node> result = new ArrayList<>();while (!zeroInQueue.isEmpty()) {Node cur = zeroInQueue.poll();result.add(cur);for (Node next : cur.nexts) {inMap.put(next, inMap.get(next) - 1);if (inMap.get(next) == 0) {zeroInQueue.add(next);}}}return result;}
}
最小生成樹算法
【定義】簡(jiǎn)單的說(shuō)就是尋找一個(gè)連接所有圖節(jié)點(diǎn)的無(wú)環(huán)子集且保證該子集所有邊的權(quán)重和最小
克魯斯卡爾算法(學(xué)完并查集后再看)
【概述】
克魯斯卡爾(Kruskal)算法從另一途徑求圖的最小生成樹。其基本思想是:
假設(shè)連通圖 G=(V,E),令最小生成樹的初始狀態(tài)為只有n個(gè)頂點(diǎn)而無(wú)邊的非連通圖T=(V,{})
該圖中每個(gè)頂點(diǎn)自成一個(gè)連通分量。
在E中選擇代價(jià)最小的邊,若該邊依附的頂點(diǎn)分別在T中不同的連通分量上,則將此邊加入到T中;
否則,舍去此邊而選擇下一條代價(jià)最小的邊。依此類推,直至T中所有頂點(diǎn)構(gòu)成一個(gè)連通分量為止
package class06;import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;//undirected graph only
public class Code04_Kruskal {// Union-Find Setpublic static class UnionFind {private HashMap<Node, Node> fatherMap;private HashMap<Node, Integer> rankMap;public UnionFind() {fatherMap = new HashMap<Node, Node>();rankMap = new HashMap<Node, Integer>();}private Node findFather(Node n) {Node father = fatherMap.get(n);if (father != n) {father = findFather(father);}fatherMap.put(n, father);return father;}public void makeSets(Collection<Node> nodes) {fatherMap.clear();rankMap.clear();for (Node node : nodes) {fatherMap.put(node, node);rankMap.put(node, 1);}}public boolean isSameSet(Node a, Node b) {return findFather(a) == findFather(b);}public void union(Node a, Node b) {if (a == null || b == null) {return;}Node aFather = findFather(a);Node bFather = findFather(b);if (aFather != bFather) {int aFrank = rankMap.get(aFather);int bFrank = rankMap.get(bFather);if (aFrank <= bFrank) {fatherMap.put(aFather, bFather);rankMap.put(bFather, aFrank + bFrank);} else {fatherMap.put(bFather, aFather);rankMap.put(aFather, aFrank + bFrank);}}}}public static class EdgeComparator implements Comparator<Edge> {@Overridepublic int compare(Edge o1, Edge o2) {return o1.weight - o2.weight;}}public static Set<Edge> kruskalMST(Graph graph) {UnionFind unionFind = new UnionFind();unionFind.makeSets(graph.nodes.values());PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());for (Edge edge : graph.edges) {priorityQueue.add(edge);}Set<Edge> result = new HashSet<>();while (!priorityQueue.isEmpty()) {Edge edge = priorityQueue.poll();if (!unionFind.isSameSet(edge.from, edge.to)) {result.add(edge);unionFind.union(edge.from, edge.to);}}return result;}
}
普里姆算法
1).輸入:一個(gè)加權(quán)連通圖,其中頂點(diǎn)集合為V,邊集合為E;
2).初始化:Vnew = {x},其中x為集合V中的任一節(jié)點(diǎn)(起始點(diǎn)),Enew = {},為空;
3).重復(fù)下列操作,直到Vnew = V:a.在集合E中選取權(quán)值最小的邊<u, v>,其中u為集合Vnew中的元素,而v不在Vnew集合當(dāng)中,并且v∈V(如果存在有多條滿足前述條 件即具有相同權(quán)值的邊,則可任意選取其中之一);b.將v加入集合Vnew中,將<u, v>邊加入集合Enew中;
4).輸出:使用集合Vnew和Enew來(lái)描述所得到的最小生成樹。
package class06;import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;// undirected graph only
public class Code05_Prim {public static class EdgeComparator implements Comparator<Edge> {@Overridepublic int compare(Edge o1, Edge o2) {return o1.weight - o2.weight;}}public static Set<Edge> primMST(Graph graph) {// 解鎖的邊進(jìn)入小根堆PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());HashSet<Node> set = new HashSet<>();// 依次挑選的邊在result里Set<Edge> result = new HashSet<>();for (Node node : graph.nodes.values()) {// 隨機(jī)挑選一個(gè)點(diǎn)// Node是開始點(diǎn)if (!set.contains(node)) {set.add(node);for (Edge edge : node.edges) { // 由一個(gè)點(diǎn),解鎖所有相連的邊priorityQueue.add(edge);}while (!priorityQueue.isEmpty()) {// 彈出解鎖的邊中,最小權(quán)值的邊Edge edge = priorityQueue.poll();// 可能的一個(gè)新節(jié)點(diǎn)Node toNode = edge.to;// 不含有的時(shí)候就是新節(jié)點(diǎn)if (!set.contains(toNode)) {set.add(toNode);result.add(edge);for (Edge nextEdge : toNode.edges) {priorityQueue.add(nextEdge);}}}}}return result;}// 請(qǐng)保證graph是連通圖// graph[i][j]表示點(diǎn)i到點(diǎn)j的距離,如果是系統(tǒng)最大值代表無(wú)路// 返回值是最小連通圖的路徑之和public static int prim(int[][] graph) {int size = graph.length;int[] distances = new int[size];boolean[] visit = new boolean[size];visit[0] = true;for (int i = 0; i < size; i++) {distances[i] = graph[0][i];}int sum = 0;for (int i = 1; i < size; i++) {int minPath = Integer.MAX_VALUE;int minIndex = -1;for (int j = 0; j < size; j++) {if (!visit[j] && distances[j] < minPath) {minPath = distances[j];minIndex = j;}}if (minIndex == -1) {return sum;}visit[minIndex] = true;sum += minPath;for (int j = 0; j < size; j++) {if (!visit[j] && distances[j] > graph[minIndex][j]) {distances[j] = graph[minIndex][j];}}}return sum;}public static void main(String[] args) {System.out.println("hello world!");}
}
迪杰斯特拉算法–求解最短路徑
package class06;import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;// no negative weight
public class Code06_Dijkstra {public static HashMap<Node, Integer> dijkstra1(Node head) {// 從Head出發(fā)到所有點(diǎn)的最小距離// key:從head出發(fā)到達(dá)key// value:從head出發(fā)到達(dá)key的最小距離// 如果在表中,沒有T的記錄,含義是從head出發(fā)到T這個(gè)點(diǎn)的距離為正無(wú)窮HashMap<Node, Integer> distanceMap = new HashMap<>();distanceMap.put(head, 0);// 已經(jīng)求過距離的節(jié)點(diǎn),存在selectedNodes中,之后不修改HashSet<Node> selectedNodes = new HashSet<>();Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes);while (minNode != null) {int distance = distanceMap.get(minNode);for (Edge edge : minNode.edges) {Node toNode = edge.to;if (!distanceMap.containsKey(toNode)) {distanceMap.put(toNode, distance + edge.weight);}distanceMap.put(edge.to, Math.min(distanceMap.get(toNode), distance + edge.weight));}selectedNodes.add(minNode);minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes);}return distanceMap;}public static Node getMinDistanceAndUnselectedNode(HashMap<Node, Integer> distanceMap, HashSet<Node> touchedNodes) {Node minNode = null;int minDistance = Integer.MAX_VALUE;for (Entry<Node, Integer> entry : distanceMap.entrySet()) {Node node = entry.getKey();int distance = entry.getValue();if (!touchedNodes.contains(node) && distance < minDistance) {minNode = node;minDistance = distance;}}return minNode;}public static class NodeRecord {public Node node;public int distance;public NodeRecord(Node node, int distance) {this.node = node;this.distance = distance;}}public static class NodeHeap {private Node[] nodes;private HashMap<Node, Integer> heapIndexMap;private HashMap<Node, Integer> distanceMap;private int size;public NodeHeap(int size) {nodes = new Node[size];heapIndexMap = new HashMap<>();distanceMap = new HashMap<>();this.size = 0;}public boolean isEmpty() {return size == 0;}public void addOrUpdateOrIgnore(Node node, int distance) {if (inHeap(node)) {distanceMap.put(node, Math.min(distanceMap.get(node), distance));insertHeapify(node, heapIndexMap.get(node));}if (!isEntered(node)) {nodes[size] = node;heapIndexMap.put(node, size);distanceMap.put(node, distance);insertHeapify(node, size++);}}public NodeRecord pop() {NodeRecord nodeRecord = new NodeRecord(nodes[0], distanceMap.get(nodes[0]));swap(0, size - 1);heapIndexMap.put(nodes[size - 1], -1);distanceMap.remove(nodes[size - 1]);nodes[size - 1] = null;heapify(0, --size);return nodeRecord;}private void insertHeapify(Node node, int index) {while (distanceMap.get(nodes[index]) < distanceMap.get(nodes[(index - 1) / 2])) {swap(index, (index - 1) / 2);index = (index - 1) / 2;}}private void heapify(int index, int size) {int left = index * 2 + 1;while (left < size) {int smallest = left + 1 < size && distanceMap.get(nodes[left + 1]) < distanceMap.get(nodes[left])? left + 1 : left;smallest = distanceMap.get(nodes[smallest]) < distanceMap.get(nodes[index]) ? smallest : index;if (smallest == index) {break;}swap(smallest, index);index = smallest;left = index * 2 + 1;}}private boolean isEntered(Node node) {return heapIndexMap.containsKey(node);}private boolean inHeap(Node node) {return isEntered(node) && heapIndexMap.get(node) != -1;}private void swap(int index1, int index2) {heapIndexMap.put(nodes[index1], index2);heapIndexMap.put(nodes[index2], index1);Node tmp = nodes[index1];nodes[index1] = nodes[index2];nodes[index2] = tmp;}}public static HashMap<Node, Integer> dijkstra2(Node head, int size) {NodeHeap nodeHeap = new NodeHeap(size);nodeHeap.addOrUpdateOrIgnore(head, 0);HashMap<Node, Integer> result = new HashMap<>();while (!nodeHeap.isEmpty()) {NodeRecord record = nodeHeap.pop();Node cur = record.node;int distance = record.distance;for (Edge edge : cur.edges) {nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance);}result.put(cur, distance);}return result;}
}
前綴樹
【簡(jiǎn)介】
前綴樹是N叉樹的一種特殊形式。通常來(lái)說(shuō),一個(gè)前綴樹是用來(lái)存儲(chǔ)字符串的。
前綴樹的每一個(gè)節(jié)點(diǎn)代表一個(gè)字符串(前綴)。每一個(gè)節(jié)點(diǎn)會(huì)有多個(gè)子節(jié)點(diǎn),通往不同子節(jié)點(diǎn)的路徑上有著不同的字符。
子節(jié)點(diǎn)代表的字符串是由節(jié)點(diǎn)本身的原始字符串,以及通往該子節(jié)點(diǎn)路徑上所有的字符組成的。
【特征】
節(jié)點(diǎn)所有的后代都與該節(jié)點(diǎn)相關(guān)的字符串有著共同的前綴。這就是前綴樹名稱的由來(lái)。
package class07;public class Code01_TrieTree {public static class TrieNode {// 邊代表字符,節(jié)點(diǎn)僅僅相當(dāng)于占位 public int path;public int end;public TrieNode[] nexts;// 當(dāng)字符內(nèi)容不僅僅是26字母的時(shí)候。可以用HashMap<Char,Node> nextspublic TrieNode() {path = 0;end = 0;nexts = new TrieNode[26];}}public static class Trie {private TrieNode root;public Trie() {root = new TrieNode();}public void insert(String word) {if (word == null) {return;}char[] chs = word.toCharArray();TrieNode node = root;int index = 0;for (int i = 0; i < chs.length; i++) {index = chs[i] - 'a';if (node.nexts[index] == null) {node.nexts[index] = new TrieNode();}node = node.nexts[index];node.path++;}node.end++;}public void delete(String word) {if (search(word) != 0) {char[] chs = word.toCharArray();TrieNode node = root;int index = 0;for (int i = 0; i < chs.length; i++) {index = chs[i] - 'a';if (--node.nexts[index].path == 0) {node.nexts[index] = null;return;}node = node.nexts[index];}node.end--;}}public int search(String word) {if (word == null) {return 0;}char[] chs = word.toCharArray();TrieNode node = root;int index = 0;for (int i = 0; i < chs.length; i++) {index = chs[i] - 'a';if (node.nexts[index] == null) {return 0;}node = node.nexts[index];}return node.end;}public int prefixNumber(String pre) {if (pre == null) {return 0;}char[] chs = pre.toCharArray();TrieNode node = root;int index = 0;for (int i = 0; i < chs.length; i++) {index = chs[i] - 'a';if (node.nexts[index] == null) {return 0;}node = node.nexts[index];}return node.path;}}public static void main(String[] args) {Trie trie = new Trie();System.out.println(trie.search("zuo"));trie.insert("zuo");System.out.println(trie.search("zuo"));trie.delete("zuo");System.out.println(trie.search("zuo"));trie.insert("zuo");trie.insert("zuo");trie.delete("zuo");System.out.println(trie.search("zuo"));trie.delete("zuo");System.out.println(trie.search("zuo"));trie.insert("zuoa");trie.insert("zuoac");trie.insert("zuoab");trie.insert("zuoad");trie.delete("zuoa");System.out.println(trie.search("zuoa"));System.out.println(trie.prefixNumber("zuo"));}
}
貪心算法
【簡(jiǎn)介】 在某一個(gè)標(biāo)準(zhǔn)下,優(yōu)先考慮最滿足標(biāo)準(zhǔn)的樣本,最后考慮最不滿足標(biāo)準(zhǔn)的樣本 最終得到一個(gè)答案的算法就稱之為貪心算法 ------------------------------------------- 不從整體最優(yōu)上加以考慮,所做出的是在某種意義上的局部最優(yōu)解 ------------------------------------------- 【解題套路】 1,實(shí)現(xiàn)一個(gè)不依靠貪心策略的解法X,可以用最暴力的嘗試 2,腦補(bǔ)出貪心策略A、貪心策略B、貪心策略C... 3,用解法X和對(duì)數(shù)器,去驗(yàn)證每一個(gè)貪心策略,用實(shí)驗(yàn)的方式得知哪個(gè)貪心策略正確 4,不要去糾結(jié)貪心策略的證明 ------------------------------------------- 【技巧】 1,根據(jù)某標(biāo)準(zhǔn)建立一個(gè)比較器來(lái)排序 2,根據(jù)某標(biāo)準(zhǔn)建立一個(gè)比較器來(lái)組成堆字符拼接最小字典序
【題目】 給定一個(gè)字符串類型的數(shù)組strs,找到一種拼接方式。 使得把所有字符串拼起來(lái)之后形成的 字符串具有最小的字典序。 package class07;import java.util.Arrays; import java.util.Comparator;public class Code02_LowestLexicography {public static class MyComparator implements Comparator<String> {@Overridepublic int compare(String a, String b) {return (a + b).compareTo(b + a);}}// String.compareTo的源碼: // public int compareTo(String anotherString) {// int len1 = value.length;// int len2 = anotherString.value.length;// int lim = Math.min(len1, len2);// char v1[] = value;// char v2[] = anotherString.value;// int k = 0;// while (k < lim) {// char c1 = v1[k];// char c2 = v2[k];// if (c1 != c2) {// return c1 - c2;// }// k++;// }// return len1 - len2;// }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 void main(String[] args) {String[] strs1 = { "jibw", "ji", "jp", "bw", "jibw" };System.out.println(lowestString(strs1));String[] strs2 = { "ba", "b" };System.out.println(lowestString(strs2));} }切金條–哈夫曼樹
【題目】 一塊金條切成兩半,是需要花費(fèi)和長(zhǎng)度數(shù)值一樣的銅板的。 比如長(zhǎng)度為20的金條,不管切成長(zhǎng)度多大的兩半,都要花費(fèi)20個(gè)銅板。 ----------------------------------------------- 一群人想整分整塊金條,怎么分最省銅板? 例如,給定數(shù)組{10,20,30},代表一共三個(gè)人,整塊金條長(zhǎng)度為10+20+30=60。 金條要分成10,20,30三個(gè)部分。 如果先把長(zhǎng)度60的金條分成10和50,花費(fèi)60; 再把長(zhǎng)度50的金條分成20和30,花費(fèi)50;一共花費(fèi)110銅板。 但是如果先把長(zhǎng)度60的金條分成30和30,花費(fèi)60; 再把長(zhǎng)度30金條分成10和20, 花費(fèi)30;一共花費(fèi)90銅板。 輸入一個(gè)數(shù)組,返回分割的最小代價(jià)。 package class07;import java.util.Comparator; import java.util.PriorityQueue;public class Code03_LessMoneySplitGold {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 MinheapComparator implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {return o1 - o2; // < 0 o1 < o2 負(fù)數(shù)}}public static class MaxheapComparator implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1; // < o2 < o1}}public static void main(String[] args) {// solutionint[] arr = { 6, 7, 8, 9 };System.out.println(lessMoney(arr));int[] arrForHeap = { 3, 5, 2, 7, 0, 1, 6, 4 };// min heapPriorityQueue<Integer> minQ1 = new PriorityQueue<>();for (int i = 0; i < arrForHeap.length; i++) {minQ1.add(arrForHeap[i]);}while (!minQ1.isEmpty()) {System.out.print(minQ1.poll() + " ");}System.out.println();// min heap use ComparatorPriorityQueue<Integer> minQ2 = new PriorityQueue<>(new MinheapComparator());for (int i = 0; i < arrForHeap.length; i++) {minQ2.add(arrForHeap[i]);}while (!minQ2.isEmpty()) {System.out.print(minQ2.poll() + " ");}System.out.println();// max heap use ComparatorPriorityQueue<Integer> maxQ = new PriorityQueue<>(new MaxheapComparator());for (int i = 0; i < arrForHeap.length; i++) {maxQ.add(arrForHeap[i]);}while (!maxQ.isEmpty()) {System.out.print(maxQ.poll() + " ");}} }會(huì)議室問題
【題目】 一些項(xiàng)目要占用一個(gè)會(huì)議室宣講,會(huì)議室不能同時(shí)容納兩個(gè)項(xiàng)目的宣講。 給你每一個(gè)項(xiàng)目開始的時(shí)間和結(jié)束的時(shí)間(給你一個(gè)數(shù) 組,里面是一個(gè)個(gè)具體 的項(xiàng)目), 你來(lái)安排宣講的日程,要求會(huì)議室進(jìn)行的宣講的場(chǎng)次最多。 返回這個(gè)最多的宣講場(chǎng)次。 package class07;import java.util.Arrays; import java.util.Comparator;public class Code04_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> {@Overridepublic 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) {} }利益最大化(賺錢問題/IPO)
【題目】 輸入: 正數(shù)數(shù)組costs 正數(shù)數(shù)組profits 正數(shù)k 正數(shù)m 含義: costs[i]表示i號(hào)項(xiàng)目的花費(fèi)profits[i]表示i號(hào)項(xiàng)目在扣除花費(fèi)之后還能掙到的錢(利潤(rùn)) k表示你只能串行的最多做k個(gè)項(xiàng)目 m表示你初始的資金 說(shuō)明: 你每做完一個(gè)項(xiàng)目,馬上獲得的收益,可以支持你去做下一個(gè)項(xiàng)目。 輸出: 你最后獲得的最大錢數(shù)。 package class07;import java.util.Comparator; import java.util.PriorityQueue;public class Code05_IPO {public static class Node {public int p;public int c;public Node(int p, int c) {this.p = p;this.c = c;}}public static class MinCostComparator implements Comparator<Node> {@Overridepublic int compare(Node o1, Node o2) {return o1.c - o2.c;}}public static class MaxProfitComparator implements Comparator<Node> {@Overridepublic int compare(Node o1, Node o2) {return o2.p - o1.p;}}public static int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {// w ==> 初始資金 // k ==> 最多買幾件商品Node[] nodes = new Node[Profits.length];for (int i = 0; i < Profits.length; i++) {nodes[i] = new Node(Profits[i], Capital[i]);}PriorityQueue<Node> minCostQ = new PriorityQueue<>(new MinCostComparator());PriorityQueue<Node> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());for (int i = 0; i < nodes.length; i++) {minCostQ.add(nodes[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;} }總結(jié)
以上是生活随笔為你收集整理的2022年1月4日|5日|6日|7日|的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: base64转音频blob
- 下一篇: 如何检查显卡适合哪个CUDA的版本?