技术干货(四)「LeetCode」51 - 60题详解( 三 )
示例:
输入: 3输出:[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ]]
向量位移public int[][] generateMatrix(int n) {int[][] res = new int[n][n];int[] dx = {0, 1, 0, -1};int[] dy = {1, 0, -1, 0};int x = 0, y = 0, d = 0;for(int i = 1; i <= n * n; i ++){res[x][y] = i;int a = x + dx[d], b = y + dy[d];// 转向的条件 1. 越界 2. 走过if(a < 0 || b < 0 || a >= n || b >= n || res[a][b] != 0){d = (d + 1) % 4;a = x + dx[d]; b = y + dy[d];}// 更新下一个点的位置x = a; y = b;}return res;}
普通模拟public int[][] generateMatrix(int n) {// 设定左、右、上、下边界int l = 0, r = n - 1, t = 0, b = n - 1;int[][] res = new int[n][n];int num = 1;while(num <= n * n){for(int i = l; i <= r; i++) res[t][i] = num++;t++;for(int i = t; i <= b; i++) res[i][r] = num++;r--;for(int i = r; i >= l; i--) res[b][i] = num++;b--;for(int i = b; i >= t; i--) res[i][l] = num++;l++;}return res;}
60. 第k个排列给出集合 [1,2,3,…,*n*] , 其所有元素共有 n! 种排列 。
按大小顺序列出所有排列情况 , 并一一标记 , 当 n = 3 时, 所有排列如下:
- "123"
- "132"
- "213"
- "231"
- "312"
- "321"
说明:
- 给定 n 的范围是 [1, 9] 。
- 给定 k 的范围是[1, n!] 。
输入: n = 3, k = 3输出: "213"
示例 2:输入: n = 4, k = 9输出: "2314"
回溯法class Solution {boolean[] used; // 记录数字是否用过int[] factorial; //阶乘数组int n , k;public String getPermutation(int n, int k) {// 初始化操作this.n = n;this.k = k;calculateFactorial(n);used = new boolean[n + 1];StringBuilder path = new StringBuilder();dfs(path, 0);return path.toString();}void dfs(StringBuilder path, int u){if(u == n) return;// 还未确定的数字的全排列个数int cnt = factorial[n - 1 - u];for(int i = 1; i <= n; i ++){if(used[i]) continue;if(cnt < k){k -= cnt;continue;}path.append(i);used[i] = true;dfs(path , u + 1);// return 后续没有必要再遍历了return;}}// 计算阶乘数组void calculateFactorial(int n){factorial = new int[n + 1];factorial[0] = 1;for(int i = 1; i <= n; i++) factorial[i] = factorial[i - 1] * i;}}
数学模拟public class Solution {public String getPermutation(int n, int k) {// 注意:相当于在 n 个数字的全排列中找到下标为 k - 1 的那个数 , 因此 k 先减 1k --;int[] factorial = new int[n];factorial[0] = 1;// 先算出所有的阶乘值for (int i = 1; i < n; i++) {factorial[i] = factorial[i - 1] * i;}// 这里使用数组或者链表都行List nums = new LinkedList<>();for (int i = 1; i <= n; i++) {nums.add(i);}StringBuilder stringBuilder = new StringBuilder();// i 表示剩余的数字个数 , 初始化为 n - 1for (int i = n - 1; i >= 0; i--) {int index = k / factorial[i] ;stringBuilder.append(nums.remove(index));k -= index * factorial[i];}return stringBuilder.toString();}}
原文链接:如果觉得本文对你有帮助 , 可以转发关注支持一下
- 浙江省|浙江的五大富豪,四位做过中国首富,仅马云的阿里就1年纳税366亿
- 三星|顶配旗舰重回最低价,三个月降价四百,12G+256G+120W
- 酷比魔方|持续推进技术储备,网易星球区块链技术或成元宇宙入场券
- OPPO|OPPO未来科技大会正式官宣,官方明示将有旗舰新品和创新技术亮相
- 支付宝|突破2项关键技术,中科院又立功了,事关量子计算和3D打印
- 东芝|如何分辨手机配置的“好坏”?认清这四点,你也能成为行家
- 微单|动辄10999元!12GB运存+512GB+微单技术,索尼的定价只能服
- 技术|张勇内部分享,解读阿里巴巴技术路线:把先进技术用到真实的大场景里去
- 电池|2021年年底买千元机,这四款用三五年没问题,十二月购机必看
- realme|盘点2021年最受好评的四款智能手表,双十二这样买不会出错