05.打表技巧和矩阵处理技巧

打表技巧

  • 1)某个面试题,输入参数类型简单,并且只有一个实际参数
  • 2)要求的返回值类型也简单,并且只有一个
  • 3)用暴力方法,把输入参数对应的返回值,打印出来看看,进而优化code

1.小虎去买苹果,商店只提供两种类型的塑料袋,每种类型都有任意数量。

1)能装下6个苹果的袋子

  1. 能装下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打印矩阵

image-20211203142256968

//    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;
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值