day26

本文介绍了四个算法题目的解决方案,包括数组中重复数字的查找、二维数组中的查找、顺时针打印矩阵和寻找字符串中第一个只出现一次的字符。通过O(N)的时间复杂度和O(1)的空间复杂度策略,展示了高效处理数组和矩阵问题的技巧。
摘要由CSDN通过智能技术生成

day26

剑指 Offer 03. 数组中重复的数字

力扣题目链接

题目

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:23

思路

要求时间复杂度 O(N),空间复杂度 O(N)。因此不能使用排序的方法,也不能使用额外的标记数组。

对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解。在调整过程中,如果第 i 位置上已经有一个值为 i 的元素,就可以知道 i 值重复。

以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复:

img

代码实现

/**
 * https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
 *
 * @author xiexu
 * @create 2022-04-18 22:59
 */
public class _剑指Offer03_数组中重复的数字 {

    public int findRepeatNumber(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            while (nums[i] != i) {
                if (nums[i] == nums[nums[i]]) {
                    return nums[i];
                }
                swap(nums, i, nums[i]);
            }
        }
        return -1;
    }

    private void swap(int[] nums, int i, int j) {
        int t = nums[i];
        nums[i] = nums[j];
        nums[j] = t;
    }

}

剑指 Offer 04. 二维数组中的查找

力扣题目链接

题目

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]

给定 target = 5,返回 true

给定 target = 20,返回 false

限制:

0 <= n <= 1000

0 <= m <= 1000

思路

要求时间复杂度 O(M + N),空间复杂度 O(1)。其中 M 为行数,N 为 列数。

该二维数组中的一个数,小于它的数一定在其左边,大于它的数一定在其下边。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来快速地缩小查找区间,每次减少一行或者一列的元素。当前元素的查找区间为左下角的所有元素。

img

代码实现

/**
 * https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/
 *
 * @author xiexu
 * @create 2022-04-18 22:34
 */
public class _剑指Offer04_二维数组中的查找 {

    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
        // 行
        int row = matrix.length;
        // 列
        int col = matrix[0].length;
        int r = 0, c = col - 1; // 从右上角开始
        while (r <= row - 1 && c >= 0) {
            if (target == matrix[r][c]) {
                return true;
            } else if (target > matrix[r][c]) {
                r++; // 往下一行查找
            } else { // target < matrix[r][c]
                c--; // 往左边查找
            }
        }
        return false;
    }

}

剑指 Offer 05. 替换空格

力扣题目链接

题目

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:

输入:s = "We are happy."
输出:"We%20are%20happy."

限制:

0 <= s 的长度 <= 10000

代码实现

/**
 * https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/
 *
 * @author xiexu
 * @create 2022-04-18 23:10
 */
public class _剑指Offer05_替换空格 {

    public String replaceSpace(String s) {
        if (s == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ') {
                sb.append("%20");
            } else {
                sb.append(s.charAt(i));
            }
        }
        return sb.toString();
    }

}

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

力扣题目链接

题目

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

示例 1:

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

示例 2:

输入: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]

限制:

0 <= matrix.length <= 100
0 <= matrix[i].length <= 100

思路

一层一层从外到里打印,观察可知每一层打印都有相同的处理步骤,唯一不同的是上下左右的边界不同了。因此使用四个变量 r1, r2, c1, c2 分别存储上下左右边界值,从而定义当前最外层。打印当前最外层的顺序:从左到右打印最上一行->从上到下打印最右一行->从右到左打印最下一行->从下到上打印最左一行。应当注意只有在 r1 != r2 时才打印最下一行,也就是在当前最外层的行数大于 1 时才打印最下一行,这是因为当前最外层只有一行时,继续打印最下一行,会导致重复打印。打印最左一行也要做同样处理。

Untitled

代码实现

/**
 * https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/
 *
 * @author xiexu
 * @create 2022-04-18 23:23
 */
public class _剑指Offer29_顺时针打印矩阵 {

    public int[] spiralOrder(int[][] matrix) {
        int m = matrix.length; // 行
        if (m == 0) {
            return new int[0];
        }
        int n = matrix[0].length; // 列
        int[] res = new int[m * n];
        int index = 0;
        // r1,r2表示上下
        int r1 = 0, r2 = m - 1;
        // c1,c2表示左右
        int c1 = 0, c2 = n - 1;
        while (r1 <= r2 && c1 <= c2) {
            // 上
            for (int i = c1; i <= c2; i++) {
                res[index++] = matrix[r1][i];
            }
            // 右
            for (int i = r1 + 1; i <= r2; i++) {
                res[index++] = matrix[i][c2];
            }
            // 下
            if (r1 != r2) {
                for (int i = c2 - 1; i >= c1; i--) {
                    res[index++] = matrix[r2][i];
                }
            }
            // 左
            if (c1 != c2) {
                for (int i = r2 - 1; i > r1; i--) {
                    res[index++] = matrix[i][c1];
                }
            }
            r1++;
            r2--;
            c1++;
            c2--;
        }
        return res;
    }

}

剑指 Offer 50. 第一个只出现一次的字符

力扣题目链接

题目

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

示例 1:

输入:s = "abaccdeff"
输出:'b'

示例 2:

输入:s = "" 
输出:' '

限制:

0 <= s 的长度 <= 50000

代码实现

/**
 * https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/
 *
 * @author xiexu
 * @create 2022-04-19 00:12
 */
public class _剑指Offer50_第一个只出现一次的字符 {

    public char firstUniqChar(String s) {
        char[] words = new char[26];
        for (int i = 0; i < s.length(); i++) {
            words[s.charAt(i) - 'a']++;
        }
        for (int i = 0; i < s.length(); i++) {
            if (words[s.charAt(i) - 'a'] == 1) {
                return s.charAt(i);
            }
        }
        return ' ';
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿小羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值