https://www.bilibili.com/video/BV1Ef4y1T7Qi
https://github.com/algorithmzuo
小虎去买苹果,商店只提供两种类型的塑料袋.每种类型都有任意数量。
小虎可以自由使用两种袋子来装苹果,但是小虎有强迫症,他要求自己使用的袋子数量必须最少,且使用的每个袋子必须装满。
给定一个正整数N,返回至少使用多少袋子。如果N无法让使用的每个袋子必须装满,返回-1
package class38;
public class Code01_AppleMinBags {
public static int minBags(int apple) {
if (apple < 0) {
return -1;
}
int bag8 = (apple >> 3);
int rest = apple - (bag8 << 3);
while(bag8 >= 0) {
// rest 个
if(rest % 6 ==0) {
return bag8 + (rest / 6);
} else {
bag8--;
rest += 8;
}
}
return -1;
}
public static int minBagAwesome(int apple) {
if ((apple & 1) != 0) { // 如果是奇数,返回-1
return -1;
}
if (apple < 18) {
return apple == 0 ? 0 : (apple == 6 || apple == 8) ? 1
: (apple == 12 || apple == 14 || apple == 16) ? 2 : -1;
}
return (apple - 18) / 8 + 3;
}
public static void main(String[] args) {
for(int apple = 1; apple < 200;apple++) {
System.out.println(apple + " : "+ minBags(apple));
}
}
}
package class38;
public class Code02_EatGrass {
// 如果n份草,最终先手赢,返回"先手"
// 如果n份草,最终后手赢,返回"后手"
public static String whoWin(int n) {
if (n < 5) {
return n == 0 || n == 2 ? "后手" : "先手";
}
// 进到这个过程里来,当前的先手,先选
int want = 1;
while (want <= n) {
if (whoWin(n - want).equals("后手")) {
return "先手";
}
if (want <= (n / 4)) {
want *= 4;
} else {
break;
}
}
return "后手";
}
public static String winner1(int n) {
if (n < 5) {
return (n == 0 || n == 2) ? "后手" : "先手";
}
int base = 1;
while (base <= n) {
if (winner1(n - base).equals("后手")) {
return "先手";
}
if (base > n / 4) { // 防止base*4之后溢出
break;
}
base *= 4;
}
return "后手";
}
public static String winner2(int n) {
if (n % 5 == 0 || n % 5 == 2) {
return "后手";
} else {
return "先手";
}
}
public static void main(String[] args) {
for (int i = 0; i <= 50; i++) {
System.out.println(i + " : " + whoWin(i));
}
}
}
定义一种数:可以表示成若干(数量>1)连续正数和的数比如:
5 =2+3,5就是这样的数
12= 3+4+5,12就是这样的数
1 不是这样的数,因为要求数量大于1个、连续正数和
2 = 1 +1,2也不是,因为等号右边不是连续正数
给定一个参数N,返回是不是可以表示成若干连续正数和的数
package class38;
public class Code03_MSumToN {
public static boolean isMSum1(int num) {
for (int start = 1; start <= num; start++) {
int sum = start;
for (int j = start + 1; j <= num; j++) {
if (sum + j > num) {
break;
}
if (sum + j == num) {
return true;
}
sum += j;
}
}
return false;
}
public static boolean isMSum2(int num) {
//
// return num == (num & (~num + 1));
//
// return num == (num & (-num));
//
//
return (num & (num - 1)) != 0;
}
public static void main(String[] args) {
for (int num = 1; num < 200; num++) {
System.out.println(num + " : " + isMSum1(num));
}
System.out.println("test begin");
for (int num = 1; num < 5000; num++) {
if (isMSum1(num) != isMSum2(num)) {
System.out.println("Oops!");
}
}
System.out.println("test end");
}
}
矩阵特殊轨迹问题
核心技巧:思想不要限制在局部坐标的变化上,要找到coding上的宏观调度
package class40;
public class Code07_ZigZagPrintMatrix {
public static void printMatrixZigZag(int[][] matrix) {
int tR = 0;
int tC = 0;
int dR = 0;
int dC = 0;
int endR = matrix.length - 1;
int endC = matrix[0].length - 1;
boolean fromUp = false;
while (tR != endR + 1) {
printLevel(matrix, tR, tC, dR, dC, fromUp);
tR = tC == endC ? tR + 1 : tR;
tC = tC == endC ? tC : tC + 1;
dC = dR == endR ? dC + 1 : dC;
dR = dR == endR ? dR : dR + 1;
fromUp = !fromUp;
}
System.out.println();
}
public static void printLevel(int[][] m, int tR, int tC, int dR, int dC, boolean f) {
if (f) {
while (tR != dR + 1) {
System.out.print(m[tR++][tC--] + " ");
}
} else {
while (dR != tR - 1) {
System.out.print(m[dR--][dC++] + " ");
}
}
}
public static void main(String[] args) {
int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
printMatrixZigZag(matrix);
}
}
package class40;
public class Code05_PrintMatrixSpiralOrder {
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--);
}
}
public static void printEdge(int[][] m, int tR, int tC, int dR, int dC) {
if (tR == dR) {
for (int i = tC; i <= dC; i++) {
System.out.print(m[tR][i] + " ");
}
} else if (tC == dC) {
for (int i = tR; i <= dR; i++) {
System.out.print(m[i][tC] + " ");
}
} else {
int curC = tC;
int curR = tR;
while (curC != dC) {
System.out.print(m[tR][curC] + " ");
curC++;
}
while (curR != dR) {
System.out.print(m[curR][dC] + " ");
curR++;
}
while (curC != tC) {
System.out.print(m[dR][curC] + " ");
curC--;
}
while (curR != tR) {
System.out.print(m[curR][tC] + " ");
curR--;
}
}
}
public static void main(String[] args) {
int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };
spiralOrderPrint(matrix);
}
}
package class40;
public class Code06_RotateMatrix {
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--);
}
}
public static void rotateEdge(int[][] m, int a, int b, int c, int d) {
int tmp = 0;
for (int i = 0; i < d - b; i++) {
tmp = m[a][b + i];
m[a][b + i] = m[c - i][b];
m[c - i][b] = m[c][d - i];
m[c][d - i] = m[a + i][d];
m[a + i][d] = tmp;
}
}
public static void printMatrix(int[][] matrix) {
for (int i = 0; i != matrix.length; i++) {
for (int j = 0; j != matrix[0].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
printMatrix(matrix);
rotate(matrix);
System.out.println("=========");
printMatrix(matrix);
}
}