LeetCode-第十二个星期

黑板异或游戏

LeetCode810题,黑板上有若干个数字,两位同学轮流擦掉一个数字轮到谁的时候,黑板上所有的数已经是0了,就是谁先获胜。
在这里插入图片描述
思路分析:
1.该题需要仔细的分析题意,当前情况分为两种。
2.当前黑板上数异或以后就已经是0了,这时候小红一上来就赢了。
3.当前黑板上的数异或不为0,这时候因为每个人擦的都是最优解,肯定不会让对方获胜,那么就要分为两种情况。
4.当黑板上的数是奇数,那么擦到最后黑板上没有数了,轮到小明上来就直接获胜了。
5.反之为偶数就是小红获胜。

 public boolean xorGame(int[] nums) {
        int x = 0;
        for (int v : nums) x ^= v;
        return x == 0 || nums.length % 2 == 0;
    }

分割回文串

LeetCode131题,给定一个字符串,将字符串切割成多个部分,要求切割出的部分,必须满足回文串的要求,将所有满足的情况添加到集合。
在这里插入图片描述
思路分析:
该题采用深度优先算法,不断的递归判断,将满足字符串加入,遍历到最后一个字符串时,将满足的集合添加进结果中,每次递归结束后,都删除集合中最后一个元素。

private void dfs(List<List<String>> ans, char[] ss, int begin, ArrayList<String> path){
        //已经遍历完了整个字符串
        if(begin == ss.length){
            //将当前集合中的字符填入
            ans.add(new ArrayList<>(path));
            return;
        }
        for(int i = begin;i < ss.length;i++){
            //判断是否满足回文字符串
            if(valid(ss, begin, i)){
                //将满足的部分加入
                path.add(new String(ss, begin, i - begin + 1));
                //从结尾处再次开始
                dfs(ans, ss, i + 1, path);
                //递归完后删除最后一个元素
                path.remove(path.size() - 1);
            }
        }
    }

    private boolean valid(char[] ss, int l, int r){
        while(l < r) if(ss[l++] != ss[r--]) return false;
        return true;
    }

T 秒后青蛙的位置

LeetCode1377题,一个无向树中青蛙站在初始节点1上,每过一秒就要跳向当前节点的子节点,只有跳到了叶子点时才不能继续往下跳,因为他不能往回跳,求该青蛙在指定时间中,在目标节点时的概率。

给你一棵由 n 个顶点组成的无向树,顶点编号从 1 到 n。青蛙从 顶点 1 开始起跳。规则如下:

在一秒内,青蛙从它所在的当前顶点跳到另一个 未访问 过的顶点(如果它们直接相连)。
青蛙无法跳回已经访问过的顶点。
如果青蛙可以跳到多个不同顶点,那么它跳到其中任意一个顶点上的机率都相同。
如果青蛙不能跳到任何未访问过的顶点上,那么它每次跳跃都会停留在原地。
无向树的边用数组 edges 描述,其中 edges[i] = [fromi, toi] 意味着存在一条直接连通 fromi 和 toi 两个顶点的边。

返回青蛙在 t 秒后位于目标顶点 target 上的概率。

 

示例 1:



输入:n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 2, target = 4
输出:0.16666666666666666 
解释:上图显示了青蛙的跳跃路径。青蛙从顶点 1 起跳,第 1 秒 有 1/3 的概率跳到顶点 2 ,然后第 2 秒 有 1/2 的概率跳到顶点 4,因此青蛙在 2 秒后位于顶点 4 的概率是 1/3 * 1/2 = 1/6 = 0.16666666666666666 。 
示例 2:



输入:n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 1, target = 7
输出:0.3333333333333333
解释:上图显示了青蛙的跳跃路径。青蛙从顶点 1 起跳,有 1/3 = 0.3333333333333333 的概率能够 1 秒 后跳到顶点 7 。 
示例 3:

输入:n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 20, target = 6
输出:0.16666666666666666

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/frog-position-after-t-seconds
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析:
遍历指定的边,记录每个顶点的父节点,和父节点下有多少子节点,遍历完成后,获得目标节点的父节点,一层一层的往上搜索,直到根节点处结束循环,计算概率值。

//下标为某个元素值,值为当前元素值的父节点
        int[] father = new int[n+1];
        for (int i = 0; i < father.length; i++) {
            //默认自己为自己的父节点
            father[i] = i;
        }
        //记录每个父节点下有多少子节点
        int[] width = new int[n+1];
        //填充元素
        for(int[] e:edges) {
            //选择小的元素作为父节点
            int fa = Math.min(e[0], e[1]);
            int son = Math.max(e[0], e[1]);
            //son的父节点为fa
            father[son] = fa;
            //父节点fa拥有的子节点数+1
            width[fa]++;
        }
        //无向数的层数
        int path = 0;
        //目标节点的分母值
        int product = 1;
        //目标数是否为叶子节点
        boolean isleaf = width[target]==0? true:false;
        //找到目标数的最顶点,这时候它的父节点就是自己
        while(target!=father[target]) {
            //层数加1,不断的往上查找
            path++;
            //获得当前目标数的父节点
            target = father[target];
            //计算当前父节点有多少子节点数
            product*=width[target];
        }
        //如果需要查找的节点是非叶子节点,并且层数小于指定秒数,则该青蛙会继续跳向当前目标的子节点
        if (!isleaf&&path<t) {
            return 0;
        }else if(path>t){
            return 0;
        }else{
            //返回最终的概率值
            return 1.0/product;
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值