一些其他的算法題
-
給定一個 0-4隨機數生成器 如何生成0-6隨機數
這個實在沒想明白怎麼做,只能抄寫在這裏,記一記,背一背。
public int rand7(){ while(true){ int a = 5*rand4() + rand4(); // 大於1 相乘 if(a < 21){ // 算出理論範圍,然後確定邊界 return a % 7; } } } //變形:如果用0-6隨機生成器生成0-9隨機數 public int rand10(){ while(true){ int a = 7*rand6() + rand6(); if(a < 41){ //排除41-48,因爲他們不能生成9,會造成各個數字出現的概率不同 return a % 10; } } }
-
在一條環路上有 N 個加油站,其中第 i 個加油站有汽油 gas[i] 升。你有一輛油箱容量無限的的汽車,從第 i 個加油站開往第 i+1 個加油站需要消耗汽油 cost[i] 升。你從其中的一個加油站出發,開始時油箱爲空。如果你可以繞環路行駛一週,則返回出發時加油站的編號,否則返回 -1。 輸入: gas = [1,2,3,4,5] cost = [3,4,5,1,2] 輸出: 3
public int canCompleteCircuit(int[] gas, int[] cost) { int n = gas.length; int sumTank = 0;//總油量 int curTank = 0;//當前油箱內的油量 int startStation = 0; for(int i = 0; i < n;i++){ sumTank += gas[i] - cost[i]; curTank += gas[i] - cost[i]; if(curTank < 0){ startStation = i + 1; curTank = 0; } } return sumTank >= 0 ? startStation : -1; // 這個是整個需要的油耗量,如果你要繞行一週,那麼這個中耗油量一定要大於等於0,不然是沒有辦法環繞一週的。用這個來標誌, }
-
劍指offer62:圓圈剩下的數字(約瑟夫環問題)
不寫了,用數組來模擬鏈表,注意下標的循環
-
🌹 給出一個區間的集合,請合併所有重疊的區間。 leetcode056
示例 1:
輸入: [[1,3],[2,6],[8,10],[15,18]]
輸出: [[1,6],[8,10],[15,18]]
解釋: 區間 [1,3] 和 [2,6] 重疊, 將它們合併爲 [1,6].
public static int[][] merge(int[][] intervals) { // 先按照區間起始位置排序 Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]); // 遍歷區間 int[][] res = new int[intervals.length][2]; int idx = -1; for (int[] interval: intervals) { // 如果結果數組是空的,或者當前區間的起始位置 > 結果數組中最後區間的終止位置, // 則不合並,直接將當前區間加入結果數組。 if (idx == -1 || interval[0] > res[idx][1]) { res[++idx] = interval; } else { // 反之將當前區間合併至結果數組的最後區間 res[idx][1] = Math.max(res[idx][1], interval[1]); } } return Arrays.copyOf(res, idx + 1); }
-
不是算法題:三個線程循環打印ABC 30次
// synchronized wait notifyAll public Mythread implements Runnale(){ private static Object obj = new Object(); private static int count = 0; private String value; private int flag; // 0 public ABCdemo1(String value,int flag) { this.value = value; this.flag = flag; } @override public void run(){ for(int i = 0; i < 10; i++){ synchronized(obj){ while(count % 3 != flag){ try{ obj.wait(); } catch (Exception e){ e.printStackTrace() } } syso(value); count++; obj.notifyAll(); } } } public static void main(String[] args) { new Thread(new ABCdemo1("A", 0)).start(); new Thread(new ABCdemo1("B", 1)).start(); new Thread(new ABCdemo1("C", 2)).start(); } }
// lock condition await singalAll public Mythread implements Runnale(){ private static int currentCount; // 線程共有,判斷所有的打印狀態 private static Lock lock = new ReentrantLock(); // 線程共有,線程鎖對象 private static Condition condition = lock.newCondition(); private int flag; // 0:打印A;1:打印B;2:打印C private String value; public ABCdemo1(String value,int flag) { this.value = value; this.flag = flag; } @override public void run(){ for(int i = 0; i < 10; i++){ try{ lock.lock(); while(count % 3 != flag){ try{ condition.await(); } catch (Exception e){ e.printStackTrace() } } syso(value); count++; obj.singalAll(); }finally{ lock.unlock(); } } } public static void main(String[] args) { new Thread(new ABCdemo1("A", 0)).start(); new Thread(new ABCdemo1("B", 1)).start(); new Thread(new ABCdemo1("C", 2)).start(); } }
-
1億個正整數,範圍是0-42億。求出現次數是2的數字,空間複雜度
這個題目是就是用位圖來做的,下面的方式其實和桶排序一樣,包括了確定位置,和桶的數量方法都是一樣的。也叫做位圖
public static void method(int[] a) { int max = 0; int min = 0; for (int i = 0; i < a.length; i++) { max = Math.max(max, a[i]); min = Math.min(min, a[i]); } int length = max / 8 - min / 8 + 1; byte[] arry = new byte[length]; for (int i = 0; i < a.length; i++) { int num = a[i]; int index = num / 8 - min / 8; int k = (num - min) % 8; if((arry[index] & 1<<k) > 0) { // 是左移 System.out.println(num + "重複了"); }else { arry[index] |= (1<<k); } } } public static void main(String[] args) { int[] a = new int[] {1,7,2,3,4,5,6,6}; method(a); }
-
分佈式多個機器生成id,如何保證不重複?
-
雪花算法,時間戳(毫秒級別)+ 機器id + 12位流水號-----這樣不依賴數據庫,生成的速度也夠快,但是依賴時鐘,如果系統時鐘回撥那麼就可能產生相同id。
-
redis集羣,每個redis設置自己的初始值,以及自增步長。然後使用它的INCR自增(原子操作)這樣就一定不會重複,當然了負載是你已經設置好的了。如此就是:
A:1,6,11,16
B:2,7,12,17
C:3,8,13,18
D:4,9,14,19
E:5,10,15,20
-
-
LRU算法知道嗎,怎麼實現的?
最近最少使用算法,多用於進程的調度,緩存淘汰等等
使用LinkedHashMap可以實現,相對於HashMap,增加了雙向鏈表,用於記錄節點之間的先後順序。LinkedHashMap的構造函數提供了一個參數accessOrder,這個參數可以指定鏈表是按照插入順序排隊還是按照訪問順序排隊。參數爲true時,就是按照訪問順序(插入,查詢)排隊,每次訪問後這個節點就會被放到鏈表頭,而長時間不被訪問的節點逐漸就到了列表尾部,當需要淘汰時,就將鏈表尾部的節點拋棄。
-
亂入的二叉樹題目:Leetcode124
給定一個非空二叉樹,返回其最大路徑和。
本題中,路徑被定義爲一條從樹中任意節點出發,達到任意節點的序列。該路徑至少包含一個節點,且不一定經過根節點。
private static int max = Integer.MIN_VALUE; public static void method(TreeNode root) { int subMethod = subMethod(root); System.out.println(max); } public static int subMethod(TreeNode root) { if (root == null) return 0; int left = Math.max(subMethod(root.left), 0); int right = Math.max(subMethod(root.right), 0); //求的過程中考慮包含當前根節點的最大路徑 max = Math.max(max, root.val + left + right); //只返回包含當前根節點和左子樹或者右子樹的路徑 return root.val + Math.max(left, right); // 我的錯誤代碼以下 // if(root == null) { // return 0; // } // int left = subMethod(root.left); // int right = subMethod(root.right); // int max = Integer.MIN_VALUE; // if(left == 0) { // max = Math.max(root.val + right,Integer.MIN_VALUE); // } // if(right == 0) { // max = Math.max(root.val + left,Integer.MIN_VALUE); // } // max = Math.max(max,root.val); // int xx = Math.max(max, max + right); // return xx; }