1:你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
来源:leetcode
思路:假设石头数量为n,每次可以拿的石头数为1-m,前提是n一定要大于m,否则第一个人直接就获胜了
那么只要你在倒数第二次拿石头后剩下的是可以拿的最大数量加1,那么必然会获胜;也就是说,只要保证剩下的石头数能被m+1整除,且你已经拿过石头了,就一定会获胜
那么:
public static boolean canWinNim(int n,int m) {
if(m==0)return false;
return n%(m+1)==0?false:true;
}
获胜情况下,第一个人要拿的数量为n%(m+1)
2:初始时有 n 个灯泡关闭。 第 1 轮,你打开所有的灯泡。 第 2 轮,每两个灯泡你关闭一次。 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。第 i 轮,每 i 个灯泡切换一次开关。 对于第 n 轮,你只切换最后一个灯泡的开关。 找出 n 轮后有多少个亮着的灯泡
来源:leetcode
思路:经过一一测试计算,结果超时了,仔细一看有规律,给n开方就行了;
//推理逻辑
// boolean arr[]=new boolean[n];
// if(n==1||n==2){
// return 1;
// }
// for (int i = 0; i <arr.length ; i++) {
// if(i%2==0)arr[i]=true;
// }
// int i=3;
// while (i<=n){
// for (int j = i-1; j <arr.length ; j+=i) {
// arr[j]=arr[j]==false?true:false;
// }
// i++;
// }
// for (int j = 0; j <arr.length ; j++) {
// if(arr[j])num++;
// }
// return num;
//具体实现
int num = 1;
while (n >= num * num) {
num++;
}
return num - 1;
3:三枚石子放置在数轴上,位置分别为 a,b,c。
每一回合,我们假设这三枚石子当前分别位于位置 x, y, z 且 x < y < z。从位置 x 或者是位置 z 拿起一枚石子,并将该石子移动到某一整数位置 k 处,其中 x < k < z 且 k != y。
当你无法进行任何移动时,即,这些石子的位置连续时,游戏结束。
要使游戏结束,你可以执行的最小和最大移动次数分别是多少? 以长度为 2 的数组形式返回答案:answer = [minimum_moves, maximum_moves]
来源:leetcode
思路:先排序,两边数字到中间隔了几个数,最大移动次数就是几,最小次数的最大值为2,即两边到中间的间隔均大于2,其次是1,即只有一边的间隔大于2,最小是0,即三数连续;
实现:
public int[] numMovesStones(int a, int b, int c) {
int arr[]=new int [2];int m=1,n=1;
int brr[]={a,b,c};
Arrays.sort(brr);
if(brr[1]-brr[0]-1==0&&brr[2]-brr[1]-1==0)arr[0]=0;
else if(brr[1]-brr[0]-1==0||brr[2]-brr[1]-1==0||brr[1]-brr[0]-1==1||brr[2]-brr[1]-1==1)arr[0]=1;
else arr[0]=2;
arr[1]=brr[1]-brr[0]-1+brr[2]-brr[1]-1;
return arr;
}
4:在一个由 ‘L’ , ‘R’ 和 ‘X’ 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
来源:leetcode
思路:将X看成空格,要从start到end要达成三个条件,
1》去掉所有X,start=end
2》start的R左边的X数量小于等于end的R左边的
3》Start的L左边的X数量大于end的L左边的
实现:
public static boolean canTransform(String start, String end) {
int l=start.length();
int i=0,j=0;
while (i<l&&j<l){
while (start.charAt(i)=='X'&&i<l-1)++i;
while (end.charAt(j)=='X'&&j<l-1)++j;
if (start.charAt(i)!=end.charAt(j)) return false;
else if (start.charAt(i)=='L' && i<j) return false;
else if (start.charAt(i)=='R' && i>j)return false;
i++;
j++;
}
return true;
}