记录一些其他算法题

一些其他的算法题

  • 给定一个 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;
    		}
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值