撲克牌的順子
一副牌里隨機(jī)抽5張牌,大小王看作任意的數(shù)字,判斷是不是順子。
方法一:先快速排序,然后比較大小和是否相等,最后判斷。
public boolean isContinuous(int[] n){
if(n==null||n.length==0)
return false;
Arrays.sort(n);
int numberOfZero=0;
int numberOfGap=0;
for(int i=0;i<n.length&&n[i]==0;i++)
++numberOfZero;
int small=numberOfZero;
int big=small+1;
while(big<n.length){
if(n[small]==n[big])
return false;
numberOfGap+=n[big]-n[small]-1;
small=big;
++big;
}
return numberOfGap>numberOfZero?false:true;
}
方法二: 新建數(shù)組,O(N)時間完成排序。
public boolean isContinuous(int [] a) {
if(a==null||a.length==0)
return false;
int []d=new int[14];
int max=-1,min=14;
for(int i=0;i<a.length;i++){
d[a[i]]++;
if(a[i]==0)
continue;
if(d[a[i]]>1)
return false;
if(a[i]>max)
max=a[i];
if(a[i]<min)
min=a[i];
}
if(Math.abs(max-min)<5)
return true;
return false;
}
約瑟夫環(huán)問題
0,1,...,n-1這n個數(shù)字排成一個圓圈,從數(shù)字0開始每次刪除圓圈第m個數(shù)字。求剩下的最后一個數(shù)字。
public static int lastRemaining(int n, int m) {
if (n < 1 || m < 1) {
return -1;
}
List<Integer> list = new LinkedList<>();
for (int i = 0; i < n; i++) {
list.add(i);
}
// 要刪除元素的位置
int idx = 0;
while (list.size() > 1) {
idx = (idx +m- 1) % list.size(); //
list.remove(idx);
}
return list.get(0);
}
數(shù)學(xué)方法。先做記錄。
public static int lastRemaining2(int n, int m) {
if(n<1||m<1)
return -1;
int last=0;
for(int i=2;i<=n;i++)
last=(last+m)%i;
return last;
}
二進(jìn)制中1的個數(shù)
只需要循環(huán)1出現(xiàn)的次數(shù),而不需要全部遍歷。如果是負(fù)數(shù)情況下,計算機(jī)用補碼形式存儲。補碼=負(fù)數(shù)反碼(除符號位全取反)+1,此時求得的是補碼的1的個數(shù)。
比如-10求得補碼中1個數(shù)為30。每一次循環(huán)都去掉了n的二進(jìn)制中最后一位1。
int numberOf1(int n){
int count=0;
while(n!=0){
++count;
n=(n-1)&n;
}
return count;
}
方法二:每次向右位移一位,注意如果用>> ,負(fù)數(shù)會陷入無限循環(huán),所以用>>>表示無符號位移。
static int numberof1(int n){
int count=0;
while(n!=0){
if((n&1)==1)
count++;
n=n>>>1;
}
return count;
}
方法三:同樣,也可以對1進(jìn)行左移
static int numberof1(int n){
int count=0;
int flag=1;
while(flag!=0){
if((n&flag)!=0)
count++;
flag=flag<<1;
}
return count;
}