記錄一些其他算法題

一些其他的算法題

  • 給定一個 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;
    		}
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章