打表技巧
- 1)某个面试题,输入参数类型简单,并且只有一个实际参数
- 2)要求的返回值类型也简单,并且只有一个
- 3)用暴力方法,把输入参数对应的返回值,打印出来看看,进而优化code
1.小虎去买苹果,商店只提供两种类型的塑料袋,每种类型都有任意数量。
1)能装下6个苹果的袋子
- 能装下8个苹果的袋子
小虎可以自由使用两种袋子来装苹果,但是小虎有强迫症,他要求自己使用的袋子数量必须最少,且使用的每个袋子必须装满。
给定一个正整数N,返回至少使用多少袋子。如果N无法让使用的每个袋子必须装满,返回-1
public static int minBags(int apple) {
if (apple < 0) {
return -1;
}
int a8 = apple >> 3;
int rest = apple - (a8 << 3);
while (a8 >= 0) {
if (rest % 6 == 0) {
return a8 + rest / 6;
} else {
a8--;
rest += 8;
}
}
return -1;
}
public static int minBagAwesome(int apple) {
if ((apple & 1) != 0) {
return -1;
}
if (apple < 18) {
return apple == 0 ? 0 : (apple == 6 || apple == 8) ? 1 : (apple == 12 || apple == 14 || apple == 16) ? 2 : -1;
} else {
return (apple - 18) / 8 + 3;
}
}
2.牛羊吃草
给定一个正整数N,表示有N份青草统一堆放在仓库里有一只牛和一只羊,牛先吃,羊后吃,它俩轮流吃草不管是牛还是羊,每一轮能吃的草量必须是:
1,4,16, 64…(4的某次方)
谁最先把草吃完,谁获胜
假设牛和羊都绝顶聪明,都想赢,都会做出理性的决定根据唯一的参数N,返回谁会赢
public static String whoWin(int n) {
if (n < 5) {
return n == 0 || n == 2 ? "后手" : "先手";
}
int base = 1;
while (base <= n) {
if (whoWin(n - base).equals("后手")) {
return "先手";
}
if (base > n / 4) {
break;
}
base <<= 2;
}
return "后手";
}
public static String winner(int n) {
return n % 5 == 0 || n % 5 == 2 ? "后手" : "先手";
}
3.连续M个正数和
定义一种数:可以表示成若干(数量>1)连续正数和的数比如:
5 = 2+3,5就是这样的数12 = 3+4+5,12就是这样的数
1不是这样的数,因为要求数量大于1个、连续正数和2 = 1+1,2也不是,因为等号右边不是连续正数
给定一个参数N,返回是不是可以表示成若干连续正数和的数
public static boolean isMSum1(int n) {
for (int i = 1; i <= n; i++) {
int sum = i;
for (int j = i + 1; j <= n; j++) {
if (sum + j > n) {
break;
}
if (sum + j == n) {
return true;
}
sum += j;
}
}
return false;
}
public static boolean isMsum2(int n) {
return (n & (n - 1)) != 0;
}
矩阵处理技巧
核心技巧:找到coding上的宏观调度
1.zigzag打印矩阵
// zigzag打印矩阵
public static void printMatrixZigZag(int[][] matrix) {
int aRow = 0;
int aCol = 0;
int bRow = 0;
int bCol = 0;
int endR = matrix.length - 1;
int endC = matrix[0].length - 1;
boolean fromUp = true;
while (aRow != endR + 1) {
printLevel(matrix, aRow, aCol, bRow, bCol, fromUp);
aRow = aCol == endC ? aRow + 1 : aRow;
aCol = aCol == endC ? aCol : aCol + 1;
bCol = bRow == endR ? bCol + 1 : bCol;
bRow = bRow == endR ? bRow : bRow + 1;
fromUp = !fromUp;
}
}
public static void printLevel(int[][] matrix, int aRow, int aCol, int bRow, int bCol, boolean fromUp) {
if (fromUp) {
while (aRow != bRow + 1) {
System.out.println(matrix[bRow--][bCol++]);
}
} else {
while (aRow != bRow + 1) {
System.out.println(matrix[aRow++][aCol--]);
}
}
}
2.转圈打印矩阵
public static void spiralOrderPrint(int[][] matrix) {
int tR = 0;
int tC = 0;
int dR = matrix.length - 1;
int dC = matrix[0].length - 1;
while (tR <= dR && tC <= dC) {
printEdge(matrix, tR, tC, dR, dC);
tR++;
tC++;
dR--;
dC--;
}
}
public static void printEdge(int[][] matrix, int tR, int tC, int dR, int dC) {
if (tR == dR) {
for (int i = tC; i <= dC; i++) {
System.out.println(matrix[tR][i]);
}
} else if (tC == dC) {
for (int i = tR; i <= dR; i++) {
System.out.println(matrix[i][tC]);
}
} else {
int curC = tC;
int curR = tR;
while (curC != dC) {
System.out.println(matrix[tR][curC++]);
}
while (curR != dR) {
System.out.println(matrix[curR++][dC]);
}
while (curC != tC) {
System.out.println(matrix[dR][curC--]);
}
while (curR != tR) {
System.out.println(matrix[curR--][tC]);
}
}
}
3.原地旋转正方形矩阵
//矩阵必须是正方形
public static void rotate(int[][] matrix) {
int a = 0;
int b = 0;
int c = matrix.length - 1;
int d = matrix[0].length - 1;
while (a < c) {
rotateEdge(matrix, a, b, c, d);
a++;
b++;
c--;
d--;
}
}
public static void rotateEdge(int[][] matrix, int a, int b, int c, int d) {
int tmp = 0;
for (int i = 0; i < d - b; i++) {
tmp = matrix[a][b + i];
matrix[a][b + i] = matrix[c - i][b];
matrix[c - i][b] = matrix[c][d - i];
matrix[c][d - i] = matrix[a + i][d];
matrix[a + i][d] = tmp;
}
}
< d - b; i++) {
tmp = matrix[a][b + i];
matrix[a][b + i] = matrix[c - i][b];
matrix[c - i][b] = matrix[c][d - i];
matrix[c][d - i] = matrix[a + i][d];
matrix[a + i][d] = tmp;
}
}