LeetCode - 1. 数组

刷题顺序来自:代码随想录

二分查找

704. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

示例1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

左闭右闭方法

public static int search1(int[] nums, int target) {
    int left = 0;
    int right = nums.length - 1;

    int result = -1;

    while (left <= right) {
        int index = (left + right) / 2;
        int mid = nums[index];
        if (mid < target) {
            left = index + 1;
        }
        else if (mid > target) {
            right = index - 1;
        }
        else {
            result = index;
            break;
        }
    }

    return result;
}

左闭右开

public static int search2(int[] nums, int target) {
    int left = 0;
    int right = nums.length;  // 不同

    int result = -1;

    // 不同
    while (left < right) {
        int index = (left + right) / 2;
        int mid = nums[index];
        if (mid < target) {
            left = index + 1;
        }
        else if (mid > target) {
            right = index;  // 不同
        }
        else {
            result = index;
            break;
        }
    }

    return result;
}

35. 搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

示例1:

输入: nums = [1,3,5,6], target = 5
输出: 2

示例2:

输入: nums = [1,3,5,6], target = 0
输出: 0
public static int searchInsert(int[] nums, int target) {
    int left = 0;
    int right = nums.length - 1;
    int result = -1;
    int mid = 0;

    while (left <= right) {
        mid = (left + right) / 2;

        if (nums[mid] < target) {
            left = mid + 1;
        }
        else if (nums[mid] > target) {
            right = mid - 1;
        }
        else {
            result = mid;
            return result;
        }
    }

    // 注意插入位置
    // 如果目标值更小,在当前位置插入
    // 如果目标值更大,在当前位置前一个位置插入
    if (nums[mid] < target) {
        result = mid + 1;
    }
    else {
        result = mid;
    }

    return result;
}

34. 在排序数组中查找元素的第一个和最后一个位置

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

示例1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
public static int[] searchRange(int[] nums, int target) {
    int[] result = {-1, -1};

    int left = 0;
    int right = nums.length - 1;

    while (left <= right) {
        int mid = (left + right) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        }
        else if (nums[mid] > target) {
            right = mid - 1;
        }
        // 找到目标
        else {
            result[0] = mid;
            result[1] = mid;

            // 左下标左移
            while (result[0] - 1 >= 0 && nums[result[0]-1] == target) {
                result[0]--;
            }
            // 右下标右移
            while (result[1] + 1 < nums.length && nums[result[1]+1] == target) {
                result[1]++;
            }
            break;
        }
    }

    return result;
}

69. sqrt(x)

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留整数部分 ,小数部分将被舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

public static int mySqrt(int x) {
    if (x <= 1) {
        return x;
    }

    int left = 1;
    int right = x / 2;

    while (left <= right) {
        int mid = (left + right) / 2;
        int result = x / mid;

        if (result > mid) {
            left = mid + 1;
        }
        else if (result < mid) {
            right = mid - 1;
        }
        else {
            return mid;
        }
    }

    // 当left > right时,应当返回right
    return right;
}

367. 有效的完全平方数

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false

示例1:

输入:num = 16
输出:true

示例2:

输入:num = 14
输出:false
public static boolean isPerfectSquare(int num) {
    if (num <= 1) {
        return true;
    }

    int left = 1;
    int right = num / 2;
    int mid = 1;

    while (left <= right) {
        mid = (left + right) / 2;
        int result = num / mid;

        if (result > mid) {
            left = mid + 1;
        }
        else if (result < mid) {
            right = mid - 1;
        }
        else {
            break;
        }
    }
    return num / mid == mid && num % mid == 0;
}

移除元素

27. 移除元素

给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用O(1)额外空间并原地修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

public static int removeElement(int[] nums, int val) {
    int count = 0;  // 记录需要移除元素的数量

    for (int i = 0; i < nums.length; i++) {
        // 当前元素需要被移除
        if (nums[i] == val) {
            count++;
        } // 如果不需要被移除,则前移
        else {
            nums[i - count] = nums[i];
        }
    }

    return nums.length - count;
}

原理相同的快慢指针法(C++版):

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
            if (val != nums[fastIndex]) {
                nums[slowIndex++] = nums[fastIndex];
            }
        }
        return slowIndex;
    }
};

26. 删除有序数组中的重复项

给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(1)额外空间的条件下完成。

快慢指针法:

public static int removeDuplicates(int[] nums) {
    if (nums.length <= 1) {
        return nums.length;
    }
    
    int slow = 0;

    for (int fast = 0; fast < nums.length; fast++) {
        if (nums[slow] != nums[fast]) {
            nums[++slow] = nums[fast];
        }
    }

    return slow + 1;
}

283. 移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

public static void moveZeroes(int[] nums) {
    int count = 0;  // 记录0的个数

    for (int i = 0; i < nums.length; i++) {
        // 记录0元素个数
        if (nums[i] == 0) {
            count++;
        }
        // 将非0元素前移
        else {
            nums[i - count] = nums[i];
        }
    }

    // 将数组尾部修改为0
    for (int i = 0; i < count; i++) {
        nums[nums.length - 1 - i] = 0;
    }
}

官方解法,交换0和非0元素:

class Solution {
    public void moveZeroes(int[] nums) {
        int n = nums.length, left = 0, right = 0;
        while (right < n) {
            if (nums[right] != 0) {
                swap(nums, left, right);
                left++;
            }
            right++;
        }
    }

    public void swap(int[] nums, int left, int right) {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }
}

844. 比较含退格的字符串

给定 st 两个字符串,当它们分别被输入到空白的文本编辑器后,请你判断二者是否相等。# 代表退格字符。

如果相等,返回 true ;否则,返回 false

注意:如果对空文本输入退格字符,文本继续为空。

public static boolean backspaceCompare(String s, String t) {
    char[] sChars = s.toCharArray();
    char[] tChars = t.toCharArray();

    int sSlow = backspace(sChars);
    int tSlow = backspace(tChars);

    // 比较2个字符串是否相等
    if (sChars.length - sSlow != tChars.length - tSlow) {
        return false;
    }
    else {
        for (int i = 0; i < sChars.length - sSlow; i++) {
            if (sChars[sSlow + i] != tChars[tSlow + i]) {
                return false;
            }
        }
    }

    return true;
}

// 输入"ab###c"
// 数组修改为"#####c",返回第一个有效元素索引5
public static int backspace(char[] chars) {
    int slow = chars.length - 1;
    int count = 0;  // 记录当前退格键的个数
    for(int fast = chars.length - 1; fast >= 0; fast--) {
        // 分为3种情况
        if (chars[fast] == '#') {
            count++;
        }
        else {
            if (count == 0) {
                swap(chars, slow, fast);
                slow--;
            }
            else {
                chars[fast] = '#';
                count--;
            }
        }
    }
    return slow + 1;
}

// 交换char数组的两个位置
public static void swap(char[] chars, int i, int j) {
    char temp = chars[i];
    chars[i] = chars[j];
    chars[j] = temp;
}

官方解法:

重构字符串

具体地,我们用栈处理遍历过程,每次我们遍历到一个字符:

  • 如果它是退格符,那么我们将栈顶弹出;
  • 如果它是普通字符,那么我们将其压入栈中。
class Solution {
    public boolean backspaceCompare(String S, String T) {
        return build(S).equals(build(T));
    }

    public String build(String str) {
        StringBuffer ret = new StringBuffer();
        int length = str.length();
        for (int i = 0; i < length; ++i) {
            char ch = str.charAt(i);
            if (ch != '#') {
                ret.append(ch);
            } else {
                if (ret.length() > 0) {
                    ret.deleteCharAt(ret.length() - 1);
                }
            }
        }
        return ret.toString();
    }
}

双指针法

一个字符是否会被删掉,只取决于该字符后面的退格符,而与该字符前面的退格符无关。因此当我们逆序地遍历字符串,就可以立即确定当前字符是否会被删掉。

具体地,我们定义skip表示当前待删除的字符的数量。每次我们遍历到一个字符:

  • 若该字符为退格符,则我们需要多删除一个普通字符,skip++
  • 若该字符为普通字符:
    • skip为0,则说明当前字符不需要删去;
    • skip不为0,则说明当前字符需要删去,skip++

这样,我们定义两个指针,分别指向两字符串的末尾。每次我们让两指针逆序地遍历两字符串,直到两字符串能够各自确定一个字符,然后将这两个字符进行比较。重复这一过程直到找到的两个字符不相等,或遍历完字符串为止。

class Solution {
    public boolean backspaceCompare(String S, String T) {
        int i = S.length() - 1, j = T.length() - 1;
        int skipS = 0, skipT = 0;

        while (i >= 0 || j >= 0) {
            while (i >= 0) {
                if (S.charAt(i) == '#') {
                    skipS++;
                    i--;
                } else if (skipS > 0) {
                    skipS--;
                    i--;
                } else {
                    break;
                }
            }
            while (j >= 0) {
                if (T.charAt(j) == '#') {
                    skipT++;
                    j--;
                } else if (skipT > 0) {
                    skipT--;
                    j--;
                } else {
                    break;
                }
            }
            if (i >= 0 && j >= 0) {
                if (S.charAt(i) != T.charAt(j)) {
                    return false;
                }
            } else {
                if (i >= 0 || j >= 0) {
                    return false;
                }
            }
            i--;
            j--;
        }
        return true;
    }
}

977. 有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

public static int[] sortedSquares(int[] nums) {
    // 用来存放平方数的新数组
    int[] squareNums = new int[nums.length];

    int right = -1;  // 指向第一个非负元素的索引的前一位
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] < 0) {
            right++;
        }
        else {
            break;
        }
    }

    int left = right;  // 最后一个负数的索引
    right++;  // 第一个非负数的索引

    for (int i = 0; i < nums.length; i++) {
        // 左指针有效且右指针无效
        // 或左指针有效或左指针的绝对值小于右指针
        if (left >= 0 && ((right >= nums.length) || -nums[left] <= nums[right])) {
            squareNums[i] = nums[left] * nums[left];
            left--;
        }
        else {
            squareNums[i] = nums[right] * nums[right];
            right++;
        }
    }

    return squareNums;
}

官方答案:双指针从数组头和尾开始,逆序地将元素的平方放入新数组。

public static int[] sortedSquares1(int[] nums) {
    // 用来存放平方数的新数组
    int[] squareNums = new int[nums.length];

    int left = 0;
    int right = nums.length - 1;
    int count = 0;  // 已放置元素数量

    while (left <= right) {
        if (nums[left] * nums[left] >= nums[right] * nums[right]) {
            squareNums[squareNums.length - count - 1] = nums[left] * nums[left];
            left ++;
        }
        else {
            squareNums[squareNums.length - count - 1] = nums[right] * nums[right];
            right--;
        }
        count++;
    }

    return squareNums;
}

滑动窗口

209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [nums l, nums l+1, ..., nums r-1, nums r] ,并返回其长度。如果不存在符合条件的子数组,返回 0

示例1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例2:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

使用滑动窗口的思想解题:

  • 每次大循环左指针向右移动一格;
  • 在一次循环中,右指针一直右移直到:
    • 右指针移到末尾
    • 或者当前子串和大于等于target
  • 更新minLen
public static int minSubArrayLen(int target, int[] nums) {
    int minLen = -1;

    int left = 0;
    int right = 0;
    int sum = nums[0];

    while (left < nums.length) {
        // 向右移动,找到符合target的子串
        while (right < nums.length - 1 && sum < target) {
            right++;
            sum += nums[right];
        }

        // 没有找到符合的子串,提前结束
        if (sum < target) {
            break;
        }

        // 更新minLen
        int curLen = right - left + 1;  // 当前长度
        if (minLen == -1 || minLen > curLen) {
            minLen = curLen;
        }

        // 左指针向右移动一格
        sum -= nums[left];
        left++;
    }

    return Math.max(minLen, 0);
}

904. 水果成篮

在一排树中,第 i 棵树产生 tree[i] 型的水果。
你可以从你选择的任何树开始,然后重复执行以下步骤:

  1. 把这棵树上的水果放进你的篮子里。如果你做不到,就停下来。
  2. 移动到当前树右侧的下一棵树。如果右边没有树,就停下来。

请注意,在选择一颗树后,你没有任何选择:你必须执行步骤 1,然后执行步骤 2,然后返回步骤 1,然后执行步骤 2,依此类推,直至停止。

你有两个篮子,每个篮子可以携带任何数量的水果,但你希望每个篮子只携带一种类型的水果。

用这个程序你能收集的水果树的最大总量是多少?

示例1:

输入:[1,2,1]
输出:3
解释:我们可以收集 [1,2,1]。

示例2:

输入:[0,1,2,2]
输出:3
解释:我们可以收集 [1,2,2]
如果我们从第一棵树开始,我们将只能收集到 [0, 1]。

实际上就是求最长的包含最多2种元素的子串长度。使用变量ab记录当前子串的两种不同元素,使用aCountbCount记录它们的数量。

public static int totalFruit(int[] fruits) {
        int total = 1;

        int a = fruits[0];
        int aCount = 1;
        int b = -1;
        int bCount = 0;

        int left = 0;
        int right = 1;

        while (Math.max(left, right) < fruits.length) {
            // 指针右移直到找到第3种元素 或者 移动到数组末尾
            while (right < fruits.length) {
                if (fruits[right] == a) {
                    aCount++;
                }
                else if (fruits[right] == b) {
                    bCount++;
                }
                else if (aCount == 0) {
                    a = fruits[right];
                    aCount++;
                }
                else if (bCount == 0) {
                    b = fruits[right];
                    bCount++;
                }
                else {
                    break;
                }
                right++;
            }
            total = Math.max(total, aCount + bCount);  // 更新最长子串的值

            // 左指针右移,直到当前子串只包含一种元素
            while (left < fruits.length && Math.min(aCount, bCount) > 0) {
                if (fruits[left] == a) {
                    aCount--;
                }
                else if (fruits[left] == b) {
                    bCount--;
                }
                left++;
            }
        }


        return total;
    }

官方答案:

class Solution {
    public int totalFruit(int[] tree) {
        int ans = 0, i = 0;
        Counter count = new Counter();
        for (int j = 0; j < tree.length; ++j) {
            count.add(tree[j], 1);
            
            // 出现第3种元素,则左指针右移,直到元素数量小于3
            while (count.size() >= 3) {
                count.add(tree[i], -1);
                if (count.get(tree[i]) == 0)
                    count.remove(tree[i]);
                i++;
            }

            ans = Math.max(ans, j - i + 1);
        }

        return ans;
    }
}

class Counter extends HashMap<Integer, Integer> {
    public int get(int k) {
        return containsKey(k) ? super.get(k) : 0;
    }

    public void add(int k, int v) {
        put(k, get(k) + v);
    }
}

76. 最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例1:

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"

示例2:

输入:s = "a", t = "a"
输出:"a"

示例3:

输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

双指针,右指针每次往右探

public static String minWindow(String s, String t) {
  // 目标串各个字符的数量
  Counter tCounter = new Counter();
  for (int i = 0; i < t.length(); i++) {
    char ch = t.charAt(i);
    tCounter.add(ch, 1);
  }

  // 用来记录当前子串的字符数量
  Counter sCounter = new Counter();

  // 用于记录最小子串的前后索引
  int minLeft = 0;
  int minRight = 0;
  int minCount = s.length() + 1;


  int left = 0;
  for (int right = 0; right < s.length(); right++) {
    // 将当前字符放入Counter
    char ch = s.charAt(right);
    if (tCounter.containsKey(ch)) {
      sCounter.add(ch, 1);
    }

    // 如果当前串已经覆盖目标串所有字符
    // 则左指针右移,直到不能覆盖为止
    while (sCounter.cover(tCounter)) {
      // 更新最小子串
      if (right - left + 1 < minCount) {
        minCount = right - left + 1;
        minLeft = left;
        minRight = right;
      }

      // 移除左指针元素后,右移一格
      if (sCounter.containsKey(s.charAt(left))) {
        sCounter.add(s.charAt(left), -1);
      }
      left++;
    }
  }

  return minCount <= s.length() ? s.substring(minLeft, minRight + 1): "";
}

class Counter extends HashMap<Character, Integer> {
    @Override
    public Integer get(Object key) {
        return containsKey(key) ? super.get(key): 0;
    }

    public void add(char key, int value) {
        put(key, get(key) + value);
    }

    // 是否覆盖了c中所有字符
    public boolean cover(Counter c) {
        boolean coverFlag = true;

        for (char ch: c.keySet()) {
            if (get(ch) < c.get(ch)) {
                coverFlag = false;
                break;
            }
        }

        return coverFlag;
    }
}

由于是字符串,char的类型不会超过256个,所以可以不使用HashMap,直接用数组表示字符出现频率,速度更快。

public static String minWindow1(String s, String t) {
    // 目标串各个字符的数量
    int[] tChars = new int[256];
    for (int i = 0; i < t.length(); i++) {
        char ch = t.charAt(i);
        tChars[ch]++;
    }

    // 用来记录当前子串的字符数量
    int[] sChars = new int[256];

    // 用于记录最小子串的前后索引
    int minLeft = 0;
    int minRight = 0;
    int minCount = s.length() + 1;


    int left = 0;
    for (int right = 0; right < s.length(); right++) {
        // 将当前字符放入Counter
        char ch = s.charAt(right);
        if (tChars[ch] > 0) {
            sChars[ch]++;
        }

        // 如果当前串已经覆盖目标串所有字符
        // 则左指针右移,直到不能覆盖为止
        while (cover(sChars, tChars)) {
            if (right - left + 1 < minCount) {
                minCount = right - left + 1;
                minLeft = left;
                minRight = right;
            }

            // 移除左指针元素后,右移一格
            if (sChars[s.charAt(left)] > 0) {
                sChars[s.charAt(left)]--;
            }
            left++;
        }
    }

    return minCount <= s.length() ? s.substring(minLeft, minRight + 1): "";
}

public static boolean cover(int[] sChars, int[] tChars) {
    boolean coverFlag = true;

    for (int i = 0; i < tChars.length; i++) {
        if (sChars[i] < tChars[i]) {
            coverFlag = false;
            break;
        }
    }

    return coverFlag;
}

螺旋矩阵

59. 螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix

示例1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例2:

输入:n = 1
输出:[[1]]
public static int[][] generateMatrix(int n) {
    int[][] matrix = new int[n][n];
    int count = 0;  // 记录现在到第几个数字

    for (int i = 0; i < n/2; i++) {
        for (int j = 0; j < 4; j++) {
            for (int k = 0; k < n-i*2-1; k++) {
                count++;
                switch (j) {
                    case 0:
                        matrix[i][i+k] = count;
                        break;
                    case 1:
                        matrix[i+k][n-i-1] = count;
                        break;
                    case 2:
                        matrix[n-i-1][n-i-1-k] = count;
                        break;
                    case 3:
                        matrix[n-i-1-k][i] = count;
                        break;
                }

            }
        }
    }

    if (n % 2 == 1) {
        matrix[n/2][n/2] = ++count;
    }

    return matrix;
}

54. 螺旋矩阵

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例1:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
public static List<Integer> spiralOrder(int[][] matrix) {
    int n = matrix.length;
    int m = matrix[0].length;

    ArrayList<Integer> list = new ArrayList<>();

    for (int i = 0; i < Math.min(n, m)/2; i++) {
        for (int j = i; j < m-i-1; j++) {
            list.add(matrix[i][j]);
        }

        for (int j = i; j < n-i-1; j++) {
            list.add(matrix[j][m-i-1]);
        }
        for (int j = i; j < m-i-1; j++) {
            list.add(matrix[n-i-1][m-j-1]);
        }
        for (int j = i; j < n-i-1; j++) {
            list.add(matrix[n-j-1][i]);
        }
    }


    if (list.size() < n*m) {
        int end = Math.min(n, m)/2;
        for (int i = end; i <= n-end-1; i++) {
            for (int j = end; j <= m-end-1; j++) {
                list.add(matrix[i][j]);
            }
        }
    }
    return list;
}

剑指 Offer 29. 顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

示例1:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
public static int[] spiralOrder(int[][] matrix) {
    if (matrix.length == 0 || matrix[0].length == 0) {
        return new int[0];
    }

    int n = matrix.length;
    int m = matrix[0].length;

    int[] result = new int[n*m];
    int pos = -1;

    for (int i = 0; i < Math.min(m, n)/2; i++) {
        for (int j = 0; j < m-i*2-1; j++) {
            result[++pos] = matrix[i][i+j];
        }
        for (int j = 0; j < n-i*2-1; j++) {
            result[++pos] = matrix[i+j][m-i-1];
        }
        for (int j = 0; j < m-i*2-1; j++) {
            result[++pos] = matrix[n-i-1][m-i-1-j];
        }
        for (int j = 0; j < n-i*2-1; j++) {
            result[++pos] = matrix[n-i-1-j][i];
        }
    }

    if (pos < result.length - 1) {
        int end = Math.min(m, n)/2;
        for (int i = end; i < n-end; i++) {
            for (int j = end; j < m-end; j++) {
                result[++pos] = matrix[i][j];
            }
        }
    }

    return result;
}
posted @ 2021-11-28 01:09  lv6laserlotus  阅读(39)  评论(0)    收藏  举报