LeetCode 292、344、557

91 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

题目:本文包含三道简单题。

  1. Nim游戏,你和你的朋友两个人一起玩Nim游戏,Nim游戏是指桌上有一堆石头,两个人轮流拿掉自己选定的1-3个石头,并且你作为先手,谁是拿掉最后一块石头的谁就是获胜者,判断你是否可以获胜。
  2. 反转字符串,给定输入的字符串,将输入的字符串数组以逆序的形式返回,并且必须原地修改输入数组,使用O(1)O(1)的空间复杂度解决本题。
  3. 反转字符串中的单词,本题和反转字符串类似,所不同的是本题是将字符串中的每个单词反转,并且保证输出的顺序和输入的顺序一致,同时不删除空格。

解题思路

对于第一题,Nim游戏,我们可以观察到,当输入的n小于等于3时我们必胜,此时可以直接输出,当大于3时则需要递归,因为我们输入的都会认定为最优解,因此必须保证无论怎么拿石头我们都必胜,可得代码如下:

public boolean canWinNim(int n) {
    if(n<=3) return true;
    return !(canWinNim(n-1)&&canWinNim(n-2)&&canWinNim(n-3));
}

最终超时,实际上我们观察规律可以发现结果每隔四是一个重复,即著名的巴什博奕,当n%(m+1)!=0时,先手总是会赢的。因此最终代码:

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

对于第二题,反转字符串没什么好说的,但我们不能用系统内置的reverse函数,这样本题就没意义了,可以以中间为间隔,依次交换两边字符即可,代码如下:

public void reverseString(char[] s) {
    int len = s.length;
    for(int i=0;i<len/2;i++){
        char temp = s[i];
        s[i] = s[len-i-1];
        s[len-i-1] = temp;
    }
}

对于第三题,可以首先将字符串以空格分开,之后依次反转,用StringBuilder接收即可,可得代码如下:

public String reverseWords(String s) {
    String[] strs = s.split(" ");
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < strs.length; i++) {
        sb.append(new StringBuilder(strs[i]).reverse());
        sb.append(" ");
    }
    return sb.toString().trim();
}