LeetCode Mock Review 2021-4-13

本文讲述了作者在解决LeetCode中的NimGame和HammingDistance问题时,从超时到找到高效解决方案的心路历程。通过数学思维和优化算法,作者将NimGame的时间复杂度降至O(1),HammingDistance则利用了二进制异或特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode Mock Review 2021-4-12

今天的Mock也很简单,是两道easy题且都是数学题。

292. Nim Game

292. Nim Game
一看到这道题我就想这不是dp问题吗。
d p [ i ] = { t u r e i ⩽ 3 ! d p [ i − 1 ] ∣ ∣ ! d p [ i − 2 ] ∣ ∣ ! d p [ i − 3 ] o t h e r w i s e dp[i]= \begin{cases} ture& i \leqslant 3\\ !dp[i-1] || !dp[i-2] ||!dp[i-3] &otherwise \end{cases} dp[i]={ture!dp[i1]!dp[i2]!dp[i3]i3otherwise
当有n颗石子时,有三种选择:拿一个,拿两个,拿三个。拿完后会剩余n-1,n-2,n-3颗石子,这时候轮到对手拿。当对手在这三种情况全部必胜的时候,说明在n颗石子时,拿取的人必输。否则拿取的人必胜。
于是我写出了第一个dp版本,用空间换时间:

class Solution {
    public boolean canWinNim(int n) {
        if(n <= 3) return true;
        boolean[] dp = new boolean[n+1];
        dp[0] = dp[1] = dp[2] = dp[3] = true;
        for(int i = 4; i <= n; i++){
            dp[i] = !dp[i-1] || !dp[i-2] || !dp[i-3];
        }
        return dp[n];
    }
}

然而Memory Limit Exceed了。
这时我注意剩n颗石子的情况只与n-1,n-2和n-3的情况有关(类似斐波那契数列的思维)。于是我写出了第二个dp版本:

class Solution{
	public boolean canWinNim(int n){
		if(n<=3) return true;
		boolean p1 = true, p2 = true, p3 = true, p = false;
		for(int i = 4; i <= n; i++){
			p = !p1 || !p2 || !p3;
			p1 = p2;
			p2 = p3;
			p3 = p;
		}
		return p;
	}
}

这下我以为稳了,结果把之前超时的用例又跑了一次发现Time Limit Exceed。
这下我有点意识到不对了,既然这样超时,那么求解过程必然可以被优化,使得时间复杂度小于O(n)。然后我在纸上写了一下n ⩽ \leqslant 8的情况。

i拿取几个最优结果
11T
22T
33T
4F
51T
62T
73T
8F

写到8时我发现了其中的规律,于是最终版本出现,时间复杂度为O(1)。

class Solution {
   public boolean canWinNim(int n) {
       return n%4!=0;
   }
}

461. Hamming Distance

461. Hamming Distance
看到题名我就想起了上计算机网络课时候学到的Hamming校验码哈哈。这道题是判断两个数的二进制表示中有多少位不一样。直接统计两数异或的结果然后求其中1的个数。

class Solution {
    public int hammingDistance(int x, int y) {
        int num = x ^ y;
        int count = 0;
        while(num != 0){
            if(num % 2 == 1) count++;
            num /= 2;
        }
        return count;
    }
}

其中可以通过优化求1的个数的过程实现更高的效率,如先与1然后右移等。


总结:第一道题在超时后心态有点崩,先去做了第二道题。然后在思考优化过程的时候在纸上写了一下就找到了规律。有时候不能光想,边写边尝试可能更加高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值