剑指Offer算法题(一)数组与矩阵

目录

[3. 数组中重复的数字](#3. 数组中重复的数字)

[4. 二维数组中的查找](#4. 二维数组中的查找)

[5. 替换空格](#5. 替换空格)

[29. 顺时针打印矩阵](#29. 顺时针打印矩阵)

[50. 第一个只出现一次的字符位置](#50. 第一个只出现一次的字符位置)


3. 数组中重复的数字

java 复制代码
package arrays_matrices;

// ====================== 核心思路 ======================
// 题目条件:长度为n,数字都在 0 ~ n-1 之间
// 利用【原地交换法】:把每个数字放到它值对应的下标位置
// 即:数字 k 应该放在下标 k 的位置
// 如果要放的位置已经是 k,说明 k 重复

// 时间复杂度:O(n), 整体是线性遍历
// 空间复杂度:O(1), 只使用了常数级额外空间,没有开辟新数组/集合,在原数组上操作
// ======================================================

public class FindDuplicateNumber {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param numbers int整型一维数组
     * @return int整型
     */
    public int duplicate(int[] numbers) {
        // write code here
        if (numbers == null || numbers.length == 0) {
            return -1;
        }
        for (int i = 0; i < numbers.length; i++) {
            while (i != numbers[i]) {
                if (numbers[i] == numbers[numbers[i]]) {
                    return numbers[i];
                } else {
                    swap(i, numbers[i], numbers);
                }
            }
        }
        return -1;
    }

    private void swap(int number1, int number2, int[] numbers) {
        int temp = numbers[number1];
        numbers[number1] = numbers[number2];
        numbers[number2] = temp;
    }

    public static void main(String[] args) {
        int[] numbers = new int[]{2, 1, 3, 2};
        FindDuplicateNumber obj = new FindDuplicateNumber();
        int res = obj.duplicate(numbers);
        System.out.println(res);
    }
}

4. 二维数组中的查找

java 复制代码
package arrays_matrices;

// ====================== 核心思路 ======================
// 题目条件:二维数组每行从左到右递增,每列从上到下递增
// 利用【右上角起点筛选法】:从矩阵最右上角开始查找
// 1. 当前值 < 目标值 → 向下移动(变大)
// 2. 当前值 > 目标值 → 向左移动(变小)
// 3. 找到相等则返回true,越界则返回false

// 时间复杂度:O(n + m), 最多遍历一行+一列,线性复杂度
// 空间复杂度:O(1), 仅使用有限变量,无额外空间开辟
// ======================================================

public class FindIn2DArray {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param target int整型
     * @param array  int整型二维数组
     * @return bool布尔型
     */
    public boolean Find(int target, int[][] array) {
        if (array == null || array.length == 0 || array[0].length == 0) {
            return false;
        }
        int x = array.length;
        int y = array[0].length;
        int i = 0;
        int j = y - 1;
        while (i < x && j >= 0) {
            if (target > array[i][j]) {
                i++;
            } else if (target < array[i][j]) {
                j--;
            } else {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        FindIn2DArray obj = new FindIn2DArray();
        int target = 1;
        int[][] array = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        boolean res = obj.Find(target, array);
        System.out.println(res);
    }
}

5. 替换空格

java 复制代码
package arrays_matrices;

// ====================== 核心思路 ======================
// 题目要求:将字符串中的空格替换成 "%20"
// 利用 String 自带的 replace 方法,直接替换所有空格
// 或者遍历字符串,遇到空格拼接 %20

// 时间复杂度:O(n),需要遍历一次字符串
// 空间复杂度:O(n),创建新字符串存储结果
// ======================================================

public class ReplaceSpace {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param s string字符串
     * @return string字符串
     */
    public String replaceSpace(String s) {
        // write code here
        if (s == null || s.isEmpty()) {
            return s;
        }
        //String 不可变,少量操作
        //StringBuilder 可变,单线程最快
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == ' ') {
                sb.append("%20");
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        ReplaceSpace obj = new ReplaceSpace();
        String res = obj.replaceSpace("We Are Happy");
        System.out.println(res); // 输出:We%20Are%20Happy
    }
}

29. 顺时针打印矩阵

java 复制代码
package arrays_matrices;

import java.util.ArrayList;

// ====================== 核心思路 ======================
// 题目要求:顺时针从外向内打印矩阵
// 利用【边界圈印法】:设定上下左右四个边界,按圈遍历
// 1. 左 → 右:打印最上面一行
// 2. 上 → 下:打印最右边一列
// 3. 右 → 左:打印最下面一行(防止单行重复)
// 4. 下 → 上:打印最左边一列(防止单列重复)
// 每打印完一圈,边界向内收缩,直到边界越界结束

// 时间复杂度:O(m*n),每个元素只遍历一次
// 空间复杂度:O(1),除结果集外仅使用常数变量
// ======================================================

public class PrintMatrixClockwise {
    public ArrayList<Integer> printMatrix(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<>();
        int r1 = 0, r2 = matrix.length - 1, c1 = 0, c2 = matrix[0].length - 1;
        while (r1 <= r2 && c1 <= c2) {
            for (int j = c1; j <= c2; j++) {
                res.add(matrix[r1][j]);
            }
            for (int i = r1 + 1; i <= r2; i++) {
                res.add(matrix[i][c2]);
            }
            if (r1 != r2)
                for (int j = c2 - 1; j >= c1; j--) {
                    res.add(matrix[r2][j]);
                }
            if (c1 != c2)
                for (int i = r2 - 1; i >= r1 + 1; i--) {
                    res.add(matrix[i][c1]);
                }
            c1++;
            c2--;
            r1++;
            r2--;
        }

        return res;
    }

    public static void main(String[] args) {
        PrintMatrixClockwise test = new PrintMatrixClockwise();
        int[][] matrix = {
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12},
                {13, 14, 15, 16}
        };
        //int[][] matrix = {{1,2,3,4}};
        ArrayList<Integer> res = test.printMatrix(matrix);
        System.out.println(res);
    }
}

50. 第一个只出现一次的字符位置

java 复制代码
package arrays_matrices;

public class FirstUniqChar {
    public int FirstNotRepeatingChar(String str) {
        // write code here
        int[] count = new int[128];
        for (int i = 0; i < str.length(); i++) {
            count[str.charAt(i)]++;
        }
        for (int i = 0; i < str.length(); i++) {
            if(count[str.charAt(i)]==1){
                return i;
            }
        }
        return -1;
    }
}
相关推荐
仰泳的熊猫1 小时前
题目2269:蓝桥杯2016年第七届真题-冰雹数
开发语言·数据结构·c++·算法·蓝桥杯
冷徹 .1 小时前
2023ICPC山东省赛
c++·算法
Sakinol#1 小时前
Leetcode Hot 100 ——回溯part01
算法·leetcode
罗湖老棍子1 小时前
【例 3】校门外的树(信息学奥赛一本通- P1537)
数据结构·算法·树状数组
guguhaohao2 小时前
平衡二叉树(AVL),咕咕咕!
数据结构·c++·算法
一叶落4382 小时前
LeetCode 137. 只出现一次的数字 II —— 位运算解法
c语言·数据结构·算法·leetcode·哈希算法
阿豪只会阿巴2 小时前
咱这后续安排
c++·人工智能·算法·leetcode·ros2
逆境不可逃2 小时前
LeetCode 热题 100 之 215. 数组中的第K个最大元素 347. 前 K 个高频元素 295. 数据流的中位数
算法·leetcode·职场和发展
凤年徐2 小时前
优选算法——滑动窗口
c++·算法