前缀树,贪心算法相关题目。
介绍前缀树
何为前缀树?如何生成前缀树:字符标在路径上(只能判断有没有以某字符串开头的字符串);扩充1:节点上标以字符结尾的字符串的数量(可以判断有没有加过某字符串);扩充2:节点增加一个数据项,到达过这个节点几次(给一个字符串,可以判断有多少字符串以它作为前缀)。可以根据功能扩充数据项。
例子:一个字符串类型的数组arr1,另一个字符串类型的数组arr2。
arr2中有哪些字符串,是arr1中出现过的?请打印 arr2中有哪些字符串,是作为arr1中某个字符串前缀出现过的?请打印 arr2中有哪些字符串,是作为arr1中某个字符串前缀出现过的?请打印arr2中出现次数最大的前缀 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 public class Code_01_TrieTree { public static class TrieNode { public int path; public int end; public TrieNode[] nexts; public 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 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 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 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; } } }
哈夫曼编码贪心
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 import java.util.Comparator;import java.util.PriorityQueue;public class Code_02_Less_Money { 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 > { @Override public int compare (Integer o1, Integer o2) { return o1 - o2; } } public static class MaxheapComparator implements Comparator <Integer > { @Override public int compare (Integer o1, Integer o2) { return o2 - o1; } } public static void main (String[] args) { int [] arr = {6 , 7 , 8 , 9 }; System.out.println(lessMoney(arr)); int [] arrForHeap = {3 , 5 , 2 , 7 , 0 , 1 , 6 , 4 }; PriorityQueue<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(); PriorityQueue<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(); PriorityQueue<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() + " " ); } } }
串行做项目,收益最大
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import java.util.Comparator;import java.util.PriorityQueue;public class Code_03_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 > { @Override public int compare (Node o1, Node o2) { return o1.c - o2.c; } } public static class MaxProfitComparator implements Comparator <Node > { @Override public int compare (Node o1, Node o2) { return o2.p - o1.p; } } public static int findMaximizedCapital (int k, int W, int [] Profits, int [] Capital) { 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; } }
一个数据流中,随时可以取得中位数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 import java.util.Arrays;import java.util.Comparator;import java.util.PriorityQueue;public class Code_04_MadianQuick { public static class MedianHolder { private PriorityQueue<Integer> maxHeap = new PriorityQueue<>(new MaxHeapComparator()); private PriorityQueue<Integer> minHeap = new PriorityQueue<>(new MinHeapComparator()); private void modifyTwoHeapsSize () { if (this .maxHeap.size() == this .minHeap.size() + 2 ) { this .minHeap.add(this .maxHeap.poll()); } if (this .minHeap.size() == this .maxHeap.size() + 2 ) { this .maxHeap.add(this .minHeap.poll()); } } public void addNumber (int num) { if (this .maxHeap.isEmpty()) { this .maxHeap.add(num); return ; } if (this .maxHeap.peek() >= num) { this .maxHeap.add(num); } else { if (this .minHeap.isEmpty()) { this .minHeap.add(num); return ; } if (this .minHeap.peek() > num) { this .maxHeap.add(num); } else { this .minHeap.add(num); } } modifyTwoHeapsSize(); } public Integer getMedian () { int maxHeapSize = this .maxHeap.size(); int minHeapSize = this .minHeap.size(); if (maxHeapSize + minHeapSize == 0 ) { return null ; } Integer maxHeapHead = this .maxHeap.peek(); Integer minHeapHead = this .minHeap.peek(); if (((maxHeapSize + minHeapSize) & 1 ) == 0 ) { return (maxHeapHead + minHeapHead) / 2 ; } return maxHeapSize > minHeapSize ? maxHeapHead : minHeapHead; } } public static class MaxHeapComparator implements Comparator <Integer > { @Override public int compare (Integer o1, Integer o2) { if (o2 > o1) { return 1 ; } else { return -1 ; } } } public static class MinHeapComparator implements Comparator <Integer > { @Override public int compare (Integer o1, Integer o2) { if (o2 < o1) { return 1 ; } else { return -1 ; } } } public static int [] getRandomArray(int maxLen, int maxValue) { int [] res = new int [(int ) (Math.random() * maxLen) + 1 ]; for (int i = 0 ; i != res.length; i++) { res[i] = (int ) (Math.random() * maxValue); } return res; } public static int getMedianOfArray (int [] arr) { int [] newArr = Arrays.copyOf(arr, arr.length); Arrays.sort(newArr); int mid = (newArr.length - 1 ) / 2 ; if ((newArr.length & 1 ) == 0 ) { return (newArr[mid] + newArr[mid + 1 ]) / 2 ; } else { return newArr[mid]; } } public static void printArray (int [] arr) { for (int i = 0 ; i != arr.length; i++) { System.out.print(arr[i] + " " ); } System.out.println(); } public static void main (String[] args) { boolean err = false ; int testTimes = 200000 ; for (int i = 0 ; i != testTimes; i++) { int len = 30 ; int maxValue = 1000 ; int [] arr = getRandomArray(len, maxValue); MedianHolder medianHold = new MedianHolder(); for (int j = 0 ; j != arr.length; j++) { medianHold.addNumber(arr[j]); } if (medianHold.getMedian() != getMedianOfArray(arr)) { err = true ; printArray(arr); break ; } } System.out.println(err ? "Oops..what a fuck!" : "today is a beautiful day^_^" ); } }
最低字典序 给定一个字符串类型的数组strs,找到一种拼接方式,使得把所有字符串拼起来之后形成的字符串具有最低的字典序。
贪心策略:str1str2拼接字典序<=str2str2拼接字典序,str1就放在str2前面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import java.util.Arrays;import java.util.Comparator;public class Code_05_LowestLexicography { 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; } }
贪心 :最多宣传场次
一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。 给你每一个项目开始的时间和结束的时间(给你一个数组,里面 是一个个具体的项目),你来安排宣讲的日程,要求会议室进行的宣讲的场次最多。返回这个最多的宣讲场次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 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 cur) { Arrays.sort(programs, new ProgramComparator()); int result = 0 ; for (int i = 0 ; i < programs.length; i++) { if (cur <= programs[i].start) { result++; cur = programs[i].end; } } return result; } }