剑指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;
    }
}
相关推荐
CoderCodingNo9 小时前
【NOIP】2011真题解析 luogu-P1003 铺地毯 | GESP三、四级以上可练习
算法
iFlyCai9 小时前
C语言中的指针
c语言·数据结构·算法
查古穆10 小时前
栈-有效的括号
java·数据结构·算法
再一次等风来10 小时前
近场声全息(NAH)仿真实现:从阵列实值信号到波数域重建
算法·matlab·信号处理·近场声全息·nah
汀、人工智能10 小时前
16 - 高级特性
数据结构·算法·数据库架构·图论·16 - 高级特性
大熊背10 小时前
利用ISP离线模式进行分块LSC校正的方法
人工智能·算法·机器学习
XWalnut10 小时前
LeetCode刷题 day4
算法·leetcode·职场和发展
蒸汽求职10 小时前
机器人软件工程(Robotics SDE):特斯拉Optimus落地引发的嵌入式C++与感知算法人才抢夺战
大数据·c++·算法·职场和发展·机器人·求职招聘·ai-native
AI成长日志11 小时前
【笔面试算法学习专栏】双指针专题·简单难度两题精讲:167.两数之和II、283.移动零
学习·算法·面试
旖-旎11 小时前
分治(库存管理|||)(4)
c++·算法·leetcode·排序算法·快速选择算法