目录

具体的思路是:
先去除字符串两端的空格,确保字符串没有多余的空格。
从字符串的最后开始向前遍历,找到第一个非空格字符的位置。
继续向前遍历,直到遇到空格字符或者到达字符串的开头,记录下遍历过程中的字符数。
返回记录的字符数,即为最后一个单词的长度。
- class Solution {
- public int lengthOfLastWord(String s) {
- // 去除字符串两端的空格
- s = s.trim();
-
- // 遍历字符串,找到最后一个单词的长度
- int length = 0;
- for (int i = s.length() - 1; i >= 0; i--) {
- if (s.charAt(i) == ' ') {
- break;
- }
- length++;
- }
-
- return length;
- }
- }
复杂度分析:
时间复杂度分析:
空间复杂度分析:
综上所述,该算法的时间复杂度为 O(n),空间复杂度为 O(1)。
LeetCode运行结果:

除了上述的方法外,还可以使用Java内置的字符串操作函数来解决这个问题。具体的思路是:
先去除字符串两端的空格,确保字符串没有多余的空格。
使用Java的 split() 函数将字符串按照空格分割成多个单词,并保存在一个字符串数组中。
如果字符串数组不为空,则最后一个单词即为数组中的最后一个元素。
返回最后一个单词的长度。
- class Solution {
- public int lengthOfLastWord(String s) {
- // 去除字符串两端的空格
- s = s.trim();
-
- // 分割字符串并获取最后一个单词的长度
- String[] words = s.split(" ");
- if (words.length == 0) {
- return 0;
- }
- return words[words.length - 1].length();
- }
-
- }
复杂度分析:
时间复杂度分析:
空间复杂度分析:
综上所述,该算法的时间复杂度为 O(n),空间复杂度为 O(n)。
LeetCode运行结果:

还可以使用正则表达式来解决这个问题。具体的思路是:
- class Solution {
- public int lengthOfLastWord(String s) {
- String[] words = s.split("\\s+");
- if (words.length == 0) {
- return 0;
- }
- String lastWord = words[words.length - 1];
- return lastWord.length();
- }
- }
复杂度分析:
LeetCode运行结果:


这道题可以使用模拟的方法来生成螺旋矩阵。具体的步骤如下:
初始化一个空的 n x n 矩阵 matrix。
定义四个变量 top、bottom、left、right,分别表示当前螺旋轮廓的上边界、下边界、左边界和右边界。
初始化变量 num 为 1,表示当前要填入的数字。
进行循环,当 num 小于等于 n 的平方时,进行以下操作:
从左到右遍历上边界,将 num 填入 matrix[top][i],并将 num 自增 1。
上边界下移一行。
若上边界超出下边界,则结束循环。
从上到下遍历右边界,将 num 填入 matrix[i][right],并将 num 自增 1。
右边界左移一列。
若右边界超出左边界,则结束循环。
从右到左遍历下边界,将 num 填入 matrix[bottom][i],并将 num 自增 1。
下边界上移一行。
若下边界超出上边界,则结束循环。
从下到上遍历左边界,将 num 填入 matrix[i][left],并将 num 自增 1。
左边界右移一列。
若左边界超出右边界,则结束循环。
返回生成的螺旋矩阵 matrix。
- class Solution {
- public int[][] generateMatrix(int n) {
- int[][] matrix = new int[n][n];
- int top = 0, bottom = n - 1, left = 0, right = n - 1;
- int num = 1;
-
- while (num <= n * n) {
- for (int i = left; i <= right; i++) {
- matrix[top][i] = num++;
- }
- top++;
- if (top > bottom) {
- break;
- }
-
- for (int i = top; i <= bottom; i++) {
- matrix[i][right] = num++;
- }
- right--;
- if (right < left) {
- break;
- }
-
- for (int i = right; i >= left; i--) {
- matrix[bottom][i] = num++;
- }
- bottom--;
- if (bottom < top) {
- break;
- }
-
- for (int i = bottom; i >= top; i--) {
- matrix[i][left] = num++;
- }
- left++;
- if (left > right) {
- break;
- }
- }
-
- return matrix;
- }
-
- }
复杂度分析:
综上所述,该算法的时间复杂度和空间复杂度均为 O(n^2)。
LeetCode运行结果:

除了模拟法之外,还可以使用递归的方法来生成螺旋矩阵。
具体的思路是,每次递归生成最外层的螺旋轮廓,并将其剥离,然后对剩余的内部矩阵进行递归生成。直到矩阵为空或只剩下一个元素时结束递归。
- class Solution {
- public int[][] generateMatrix(int n) {
- int[][] matrix = new int[n][n];
- generateMatrix(matrix, 0, n - 1, 1);
- return matrix;
- }
-
- private void generateMatrix(int[][] matrix, int start, int end, int num) {
- if (start > end) {
- return;
- }
-
- // 生成最外层的螺旋轮廓
- for (int i = start; i <= end; i++) {
- matrix[start][i] = num++;
- }
- for (int i = start + 1; i <= end; i++) {
- matrix[i][end] = num++;
- }
- for (int i = end - 1; i >= start; i--) {
- matrix[end][i] = num++;
- }
- for (int i = end - 1; i > start; i--) {
- matrix[i][start] = num++;
- }
-
- // 递归生成内部矩阵
- generateMatrix(matrix, start + 1, end - 1, num);
- }
-
- }
复杂度分析:
综上所述,该算法的时间复杂度和空间复杂度均为 O(n^2)。
LeetCode运行结果:

除了模拟和递归之外,还可以使用迭代的方法来生成螺旋矩阵。该方法使用四个变量表示当前要填入的数字、当前螺旋轮廓的上、下、左、右边界,并按照规律依次填入数字。
- class Solution {
- public int[][] generateMatrix(int n) {
- int[][] matrix = new int[n][n];
- int num = 1;
- int top = 0, bottom = n - 1, left = 0, right = n - 1;
-
- while (num <= n * n) {
- // 从左到右填入上边界
- for (int i = left; i <= right; i++) {
- matrix[top][i] = num++;
- }
- top++;
-
- // 从上到下填入右边界
- for (int i = top; i <= bottom; i++) {
- matrix[i][right] = num++;
- }
- right--;
-
- // 从右到左填入下边界
- for (int i = right; i >= left; i--) {
- matrix[bottom][i] = num++;
- }
- bottom--;
-
- // 从下到上填入左边界
- for (int i = bottom; i >= top; i--) {
- matrix[i][left] = num++;
- }
- left++;
- }
-
- return matrix;
- }
-
-
- }
复杂度分析:
对于迭代方法来说,时间复杂度和空间复杂度仍然为O(n^2)。
综上所述,迭代方法的时间复杂度和空间复杂度均为O(n^2)。
LeetCode运行结果:

除了模拟、递归和迭代之外,还可以使用数学规律的方法来生成螺旋矩阵。
在这种方法中,可以将生成螺旋矩阵的过程看作是按层进行填充的过程。首先确定每一层的起始位置和结束位置,并根据数学规律逐步填入数字。
- class Solution {
- public int[][] generateMatrix(int n) {
- int[][] matrix = new int[n][n];
- int num = 1;
- int startRow = 0, endRow = n - 1, startCol = 0, endCol = n - 1;
-
- while (startRow <= endRow && startCol <= endCol) {
- // 填充当前层的上边界
- for (int i = startCol; i <= endCol; i++) {
- matrix[startRow][i] = num++;
- }
- startRow++;
-
- // 填充当前层的右边界
- for (int i = startRow; i <= endRow; i++) {
- matrix[i][endCol] = num++;
- }
- endCol--;
-
- if (startRow <= endRow) {
- // 填充当前层的下边界
- for (int i = endCol; i >= startCol; i--) {
- matrix[endRow][i] = num++;
- }
- endRow--;
- }
-
- if (startCol <= endCol) {
- // 填充当前层的左边界
- for (int i = endRow; i >= startRow; i--) {
- matrix[i][startCol] = num++;
- }
- startCol++;
- }
- }
-
- return matrix;
- }
-
- }
复杂度分析:
对于数学规律方法来说,时间复杂度和空间复杂度仍然为O(n^2)。
综上所述,数学规律方法的时间复杂度和空间复杂度均为O(n^2)。
LeetCode运行结果:


题目要求按照大小顺序列出所有排列情况,并找出第k个排列。
我们可以使用回溯算法来解决这个问题。具体步骤如下:
used,用于标记数字是否已经被使用过。permutation,用于保存当前的排列结果。count,用于计数当前的排列序号。backtrack,参数为当前处理的数字num和目标排列的长度n。
num等于n,表示已经生成了一个完整的排列,此时count加一。
count等于k,说明已经找到了第k个排列,将permutation作为结果返回。1到n:
used[i]为false),则将其加入到permutation中,并将used[i]标记为true,然后递归调用backtrack(num + 1, n)。
permutation中移除,并将used[i]标记为false。- class Solution {
- public String getPermutation(int n, int k) {
- boolean[] used = new boolean[n + 1];
- StringBuilder permutation = new StringBuilder();
- int[] count = new int[1];
-
- backtrack(0, n, k, used, permutation, count);
-
- return permutation.toString();
- }
-
- private boolean backtrack(int num, int n, int k, boolean[] used, StringBuilder permutation, int[] count) {
- if (num == n) {
- count[0]++;
- if (count[0] == k) {
- return true;
- }
- return false;
- }
-
- for (int i = 1; i <= n; i++) {
- if (!used[i]) {
- permutation.append(i);
- used[i] = true;
-
- if (backtrack(num + 1, n, k, used, permutation, count)) {
- return true;
- }
-
- permutation.deleteCharAt(permutation.length() - 1);
- used[i] = false;
- }
- }
-
- return false;
- }
- }
复杂度分析:
设n为给定数字的大小。
综上所述,该算法的时间复杂度为O(n * n!),空间复杂度为O(n)。由于n的范围限制为1 <= n <= 9,因此算法的运行时间是可以接受的。
LeetCode运行结果:

除了回溯算法,我们还可以使用迭代的思路来解决这个问题。
该方法首先通过迭代生成了数字列表和阶乘数组,然后进行迭代过程来计算每一位上的数字,并将其加入到结果中,直到得到第k个排列。
- class Solution {
- public String getPermutation(int n, int k) {
- // 初始化数字列表和阶乘数组
- List
nums = new ArrayList<>(); - int[] factorials = new int[n+1];
- factorials[0] = 1;
- for (int i = 1; i <= n; i++) {
- nums.add(i);
- factorials[i] = factorials[i-1] * i;
- }
-
- // k需要减一,方便对索引的计算
- k--;
-
- StringBuilder sb = new StringBuilder();
- for (int i = n; i >= 1; i--) {
- int index = k / factorials[i-1]; // 当前位上的数字在数字列表中的索引
- sb.append(nums.remove(index)); // 将当前位上的数字加入到结果中
- k %= factorials[i-1]; // 更新k
- }
-
- return sb.toString();
- }
- }
复杂度分析:
时间复杂度分析:
空间复杂度分析:
综上所述,该算法的时间复杂度为 O(n^2),空间复杂度为 O(n)。
LeetCode运行结果:
