Leetcode contests 95 题解

简介: 用容斥原理可以计算出一个数字Num之下有多少个A或B的倍数cnt,我们从最大值二分这个数字Num,拿cnt和N做比较来决定二分的走向,最终l和r肯定会收敛到一起,这就是我们要的结果了。 这道题的数值范围不是特别大 ,用long就可以完全满足需求了。

876. Middle of the Linked List

 简单题,我的做法是先数下个数,然后知道中间节点是第几个了。


class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode p = head;
        int cnt = 0;
        while (p != null) {
            cnt++;
            p = p.next;
        }
        cnt /=2;
        p = head;
        while (cnt>0) {
            p = p.next;
            cnt--;
        }
        return p;
    }
}

877. Stone Game

 这道题我用了记忆化搜索,用递归暴搜可能是能获取到正确结果的,但是直接的递归在重复计算好东西,所以我用dp数组把计算出来的结果保存起来,用的时候直接调取结果,可以减少递归树中重复的部分。

 dp[i][j][0] 表示[i,j]区间Alice能取到的最优结果,dp[i][j][1]表示[i,j]区间Lee能取到最优的结果。

class Solution {
    int[][][] dp;
    public boolean stoneGame(int[] piles) {
        dp = new int[piles.length][piles.length][2];
        int len = piles.length;
        int sum = 0;
        for (int i = 0; i < len; i++) {
            dp[i][i][0] = piles[i];
            dp[i][i][1] = piles[i];
            sum += piles[i];
        }
        return  help(0, len-1, 0, piles)> sum/2;
    }
    private int help(int i, int j, int pos, int[] piles) {
        if (dp[i][j][pos] != 0) {
            return dp[i][j][pos];
        }
        int newpos = pos^1;
        dp[i][j][newpos] = Math.max(help(i+1, j, newpos, piles), help(i, j-1, newpos, piles));
        dp[i][j][pos] = Math.max(help(i+1, j, newpos, piles)+piles[i+1], help(i, j-1, newpos, piles)+piles[j-1]);
        return dp[i][j][pos];
    }
}

878. Nth Magical Number

  用容斥原理可以计算出一个数字Num之下有多少个A或B的倍数cnt,我们从最大值二分这个数字Num,拿cnt和N做比较来决定二分的走向,最终l和r肯定会收敛到一起,这就是我们要的结果了。

  这道题的数值范围不是特别大 ,用long就可以完全满足需求了。

class Solution {
    private long gcd(long x, long y) {
        if (x%y == 0)
            return y;
        return gcd(y, x%y);
    }
    public int nthMagicalNumber(int N, int A, int B) {
        long C = 1l*A*B/gcd(A, B);
        long r = 1000000000l*40000*40000;
        long l = 0;
        while(l < r) {
            long mid = (l+r)/2;
            long cnt = mid/A + mid/B - mid/C;
            if (cnt < N)
                l = mid+1;
            else
                r = mid;
        }
        return (int) (l%1000000007);
    }
}
目录
相关文章
|
6月前
LeetCode
LeetCode
40 0
|
6月前
leetcode-1219:黄金矿工
leetcode-1219:黄金矿工
79 0
|
6月前
|
消息中间件 Kubernetes NoSQL
LeetCode 1359、1360
LeetCode 1359、1360
|
算法
LeetCode——944. 删列造序
LeetCode——944. 删列造序
110 0
leetcode第36题
一个 9 * 9 的数独的棋盘。判断已经写入数字的棋盘是不是合法。需要满足下边三点, • 每一行的数字不能重复 • 每一列的数字不能重复 • 9 个 3 * 3 的小棋盘中的数字也不能重复。 只能是 1 - 9 中的数字,不需要考虑数独最后能不能填满
leetcode第36题
|
存储
leetcode第52题
可以发现对于同一条副对角线,row + col 的值是相等的。 对于同一条主对角线,row - col 的值是相等的。 我们同样可以用一个 bool 型数组,来保存当前对角线是否有元素,把它们相加相减的值作为下标。 对于 row - col ,由于出现了负数,所以可以加 1 个 n,由 [ - 3, 3 ] 转换为 [ 1 , 7 ] 。
leetcode第52题
leetcode第55题
当自己按照 45 题的思路写完的时候,看 Solution 的时候都懵逼了,这道题竟然这么复杂?不过 Solution 把问题抽象成动态规划的思想,以及优化的过程还是非常值得学习的。
leetcode第55题
leetcode第31题
我们想几个问题。 要想使得数字变大,只要任意一位变大就可以。 要想得到刚好大于原来的数字,要变个位。 这里变大数字,只能利用交换。 如果从个位开始,从右往左进行,找一个比个位大的,交换过来,个位的数字交换到了更高位,由于个位的数字较小,所以交换过去虽然个位变大了,但数字整体变小了。例如 1 3 2,把 2 和 3 交换,变成 1 2 3,个位变大了,但整体数字变小了。 个位不行,我们再看十位,如果从十位左边找一个更大的数字交换过来,和个位的情况是一样的,数字会变小。例如 4 1 2 3,把 2 和 4 交换,2 1 4 3,数字会变小。如果从
leetcode第31题
leetcode第20题
括号匹配问题。 如果只有一种括号,我们完全可以用一个计数器 count ,遍历整个字符串,遇到左括号加 1 ,遇到右括号减 1,遍历结束后,如果 count 等于 0 ,则表示全部匹配。但如果有多种括号,像 ( [ ) ] 这种情况它依旧会得到 0,所以我们需要用其他的方法。 栈! 遍历整个字符串,遇到左括号就入栈,然后遇到和栈顶对应的右括号就出栈,遍历结束后,如果栈为空,就表示全部匹配。
leetcode第20题