package neu.yanyingnan.offer;
import java.util.LinkedList;
/*题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。
HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:
首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。
每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,
从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,
可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。
请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)*/
publicclass Solution_46 {
/* public int LastRemaining_Solution(int n, int m) {//方法一 :链表法 时间复杂度O(mn) 空间 O(n)
LinkedList<Integer> list = new LinkedList<Integer>();//用链表模拟删除过程for(int i=0; i<n; i++)//将编号加入链表
list.add(i);
int del = 0;//记录要删除的下标,初始为零while(list.size()>1){
del = (del+m-1)%list.size();//这句话是核心 在原来的del位置基础上再加m-1 % 起到了循环的效果
list.remove(del);
}
return list.size()==1? list.get(0): -1;
}*/
/* public int LastRemaining_Solution(int n, int m) {//方法二 :递推公式循环法 时间复杂度O(n) 空间 O(1)if (m < 1 || n < 1) //递推公式:f[1,m]=0;(n=1) f[n,m]=(f[n-1,m]+m)%n;(n>1)return -1;
int last = 0;
for (int i = 2; i <= n; i++) // i代表人数,直到循环到人数n
last = (last + m) % i;
return last;
}*/
public int LastRemaining_Solution(int n, int m) {//方法三:递推公式递归法 时间复杂度O(n) 空间 O(1)if(m<1 || n<1)
return -1;
else{
if (n==1) //递推公式:f[1,m]=0;(n=1) f[n,m]=(f[n-1,m]+m)%n;(n>1)return0;
return (LastRemaining_Solution(n-1, m)+m) % n;
}
}
}
扑克牌的顺子
package neu.yanyingnan.offer;
import java.util.Arrays;
/*题目描述
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...
他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!
“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,
他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。
上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。
LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何。
为了方便起见,你可以认为大小王是0。*/
publicclass Solution_45 {
/* public boolean isContinuous(int [] numbers) {
if(numbers == null || numbers.length != 5)
returnfalse;
Arrays.sort(numbers);//第一步:排序if(numbers[numbers.length-2]==0)//如果排好序的数组中倒数第二个数为零,那么一定可以连续returntrue;
int zero = 0;
int gap = 0;
for(int i=0; i<numbers.length-1; i++){
if(numbers[i]==0)//第二步:统计0的个数
zero++;
else{
if(numbers[i] == numbers[i+1])//若有相等 一定不能有连续的结果returnfalse;
else{
gap += (numbers[i]-i)-(numbers[i+1]-(i+1));//第三步:统计间隔
}
}
}
if(Math.abs(gap)==zero)
returntrue;
elsereturnfalse;
}*/
// 考略到顺子的特性,最大值和最小值之差绝对为4, // 然而又有大小王的存在,所以a[4]-a[index] <=4 // 此题关键是去重和0的个数,还有最大最小的差值 public boolean isContinuous(int[] numbers) {
if (numbers == null || numbers.length != 5)
returnfalse;
Arrays.sort(numbers);
if(numbers[numbers.length-2]==0)//如果排好序的数组中倒数第二个数为零,那么一定可以连续returntrue;
// 大小王看成0,最多4个 // index为0的个数,也是第一个不为0的数字下标
int index = 0;
while (numbers[index] == 0)
index++;
for (int i = index; i < numbers.length - 1; i++){
// 判断有没有重复扑克 if (numbers[i] == numbers[i + 1])
returnfalse;
}
return numbers[4] - numbers[index] <= 4; //最大最小值差值 这个思路 比我的思路叼一点!
}
}
(完成)菲波那切数列
/*题目描述:
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39*/publicclass Solution_07 {
publicintFibonacci(int n) {//这是迭代法 时间效率为O(n)//可以用递归 代码超级简单 效率不好 面试不能过if(n < 2)
return n;
int f0 = 0;
int f1 = 1;
int tmp = 0;//一定要引入tmp;for(int i=2; i<=n; i++){
tmp = f1;
f1 = f0 + f1;
f0 = tmp;
}
return f1;
}
(完成)跳台阶
/*题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。*/publicclass Solution_08 {
publicintJumpFloor(int target) {//只是把菲波那切数列现实化if(target < 3)
return target;
int f1 = 1;
int f2 = 2;
int tmp;
for(int i=3; i<=target; i++){
tmp = f2;
f2 = f1 + f2;
f1 = tmp;
}
return f2;
}
}