算法训练-模拟

模拟

 leetcode415. 字符串相加

法一:模拟+双指针

 leetcode796. 旋转字符串

法一:模拟

法二:搜索子字符串

leetcode946. 验证栈序列

法一:模拟

leetcode6. Z 字形变换

法一:巧设flag 

leetcode54. 螺旋矩阵

法一:按层模拟

leetcode59. 螺旋矩阵 II

法一:按层模拟

leetcode48. 旋转图像

法一:辅助数组

法二:原地旋转

leetcode8. 字符串转换整数 (atoi)

法一:模拟


leetcode415. 字符串相加

415. 字符串相加icon-default.png?t=O83Ahttps://leetcode.cn/problems/add-strings/

法一:模拟+双指针

public class Method01 {
    // 方法:将两个字符串表示的非负整数相加
    public String addStrings(String num1, String num2) {
        StringBuilder sb = new StringBuilder(); // 创建一个 StringBuilder 用于存储结果
        int i = num1.length() - 1, j = num2.length() - 1; // 初始化指针 i 和 j 分别指向两个字符串的末尾
        int jinwei = 0; // 初始化进位
        int sum = 0; // 初始化和

        // 当 i 或 j 还在范围内时循环
        while (i >= 0 || j >= 0) {
            // 计算当前位的和,包括进位和当前位的数字
            sum = jinwei + (i >= 0 ? num1.charAt(i) - '0' : 0) + (j >= 0 ? num2.charAt(j) - '0' : 0);
            jinwei = sum / 10; // 更新进位
            sb.append(sum % 10); // 将当前位结果添加到 StringBuilder 中
            i--; // 指向 num1 的前一位
            j--; // 指向 num2 的前一位
        }

        // 如果最后还有进位,则在前面加上 '1',否则直接返回结果
        return jinwei == 0 ? sb.reverse().toString() : ("1" + sb.reverse().toString());
    }
}

 leetcode796. 旋转字符串

796. 旋转字符串icon-default.png?t=O83Ahttps://leetcode.cn/problems/rotate-string/

法一:模拟

public class Method01 {
    public boolean rotateString(String s, String goal) {
        if(s.length()!=goal.length()){
            return false;
        }
        for (int i = 0; i < s.length(); i++) {
            boolean flag=true;
            for (int j = 0; j < goal.length(); j++) {
                if(s.charAt(j)!=goal.charAt((i+j)%goal.length())){
                    flag=false;
                    break;
                }
            }
            if(flag){
                return true;
            }
        }
        return false;
    }
}

法二:搜索子字符串

public class Method02 {
    // 方法:检查字符串 s 是否可以通过旋转得到字符串 goal
    public boolean rotateString(String s, String goal) {
        // 判断 s 和 goal 是否长度相等,以及 goal 是否是 s+s 的子串
        return s.length() == goal.length() && (s + s).contains(goal);
    }
}

leetcode946. 验证栈序列

946. 验证栈序列icon-default.png?t=O83Ahttps://leetcode.cn/problems/validate-stack-sequences/

法一:模拟

public class Method01 {
    // 方法:验证推入和弹出序列是否可以表示栈的合法操作
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> stack = new Stack<>(); // 创建一个栈
        int i = 0; // 初始化弹出序列的索引

        // 遍历每一个推入的元素
        for (int push : pushed) {
            stack.push(push); // 将当前元素推入栈
            // 当栈不为空,并且栈顶元素等于当前要弹出的元素时
            while (!stack.isEmpty() && stack.peek() == popped[i]) {
                stack.pop(); // 弹出栈顶元素
                i++; // 移动到下一个要弹出的元素
            }
        }

        // 返回栈是否为空,即所有元素是否都已按照顺序弹出
        return stack.isEmpty();
    }
}

leetcode6. Z 字形变换

6. Z 字形变换icon-default.png?t=O83Ahttps://leetcode.cn/problems/zigzag-conversion/

法一:巧设flag 

public class Method01 {
    public String convert(String s, int numRows) {
        // 处理边界条件:当输入字符串为 null 或者行数小于 2 时,直接返回原字符串
        if (s == null || numRows < 2) return s;

        // 创建一个 ArrayList,存储每一行的字符串内容
        List<StringBuilder> rows = new ArrayList<StringBuilder>();

        // 初始化每一行,以 StringBuilder 的形式存储
        for (int i = 0; i < numRows; i++) {
            rows.add(new StringBuilder());
        }

        // 初始化行索引 i 和方向标志 flag
        int i = 0, flag = -1; // flag 用于控制行的移动方向

        // 遍历输入字符串的每一个字符
        for (char c : s.toCharArray()) {
            // 将字符追加到当前行
            rows.get(i).append(c);

            // 当到达顶行或底行时,反转方向
            if (i == 0 || i == numRows - 1) {
                flag = -flag; // 反转方向
            }

            // 根据当前方向更新行索引 i
            i += flag; // flag 为 -1 时,i 减 1;为 1 时,i 加 1
        }

        // 创建一个新的 StringBuilder,用于构建最终结果
        StringBuilder res = new StringBuilder();

        // 将每一行的 StringBuilder 内容添加到最终结果中
        for (StringBuilder row : rows) {
            res.append(row); // 拼接每一行的内容
        }

        // 返回最终结果的字符串形式
        return res.toString();
    }
}

leetcode54. 螺旋矩阵

54. 螺旋矩阵icon-default.png?t=O83Ahttps://leetcode.cn/problems/spiral-matrix/

法一:按层模拟

public class Method01 {
    public List<Integer> spiralOrder(int[][] matrix) {
        // 创建一个列表来存储结果
        List<Integer> res = new ArrayList<>();
        // 定义四个边界,left、right、top、bottom分别表示左、右、上、下边界
        int left = 0, right = matrix[0].length - 1, top = 0, bottom = matrix.length - 1;

        // 不断螺旋遍历,直到所有元素都被访问
        while (true) {
            // 从左到右遍历当前的上边界
            for (int i = left; i <= right; i++) {
                res.add(matrix[top][i]);
            }
            // 更新上边界
            if (++top > bottom) {
                break; // 如果上边界超过下边界,结束循环
            }

            // 从上到下遍历当前的右边界
            for (int i = top; i <= bottom; i++) {
                res.add(matrix[i][right]);
            }
            // 更新右边界
            if (--right < left) {
                break; // 如果右边界小于左边界,结束循环
            }

            // 从右到左遍历当前的下边界
            for (int i = right; i >= left; i--) {
                res.add(matrix[bottom][i]);
            }
            // 更新下边界
            if (--bottom < top) {
                break; // 如果下边界小于上边界,结束循环
            }

            // 从下到上遍历当前的左边界
            for (int i = bottom; i >= top; i--) {
                res.add(matrix[i][left]);
            }
            // 更新左边界
            if (++left > right) {
                break; // 如果左边界超过右边界,结束循环
            }
        }
        // 返回结果列表
        return res;
    }
}

leetcode59. 螺旋矩阵 II

59. 螺旋矩阵 IIicon-default.png?t=O83Ahttps://leetcode.cn/problems/spiral-matrix-ii/

法一:按层模拟

public class Method01 {
    public int[][] generateMatrix(int n) {
        // 创建一个 n x n 的二维数组,用于存储结果
        int[][] res = new int[n][n];
        // 定义四个边界,left、right、top、bottom分别表示左、右、上、下边界
        int left = 0, right = n - 1, top = 0, bottom = n - 1;
        // 定义一个变量用于填充矩阵的数字,从 1 开始
        int num = 1;

        // 不断螺旋填充矩阵,直到所有位置都被填充
        while (true) {
            // 从左到右遍历当前的上边界并填充数字
            for (int i = left; i <= right; i++) {
                res[top][i] = num++;
            }
            // 更新上边界
            if (++top > bottom) {
                break; // 如果上边界超过下边界,结束循环
            }

            // 从上到下遍历当前的右边界并填充数字
            for (int i = top; i <= bottom; i++) {
                res[i][right] = num++;
            }
            // 更新右边界
            if (--right < left) {
                break; // 如果右边界小于左边界,结束循环
            }

            // 从右到左遍历当前的下边界并填充数字
            for (int i = right; i >= left; i--) {
                res[bottom][i] = num++;
            }
            // 更新下边界
            if (--bottom < top) {
                break; // 如果下边界小于上边界,结束循环
            }

            // 从下到上遍历当前的左边界并填充数字
            for (int i = bottom; i >= top; i--) {
                res[i][left] = num++;
            }
            // 更新左边界
            if (++left > right) {
                break; // 如果左边界超过右边界,结束循环
            }
        }

        // 返回填充完成的矩阵
        return res;
    }
}

leetcode48. 旋转图像

48. 旋转图像icon-default.png?t=O83Ahttps://leetcode.cn/problems/rotate-image/

法一:辅助数组

public class Method01 {
    public void rotate(int[][] matrix) {
        // 获取矩阵的大小 n
        int n = matrix.length;
        // 创建一个临时矩阵,用于存储旋转后的结果
        int[][] temp = new int[n][n];

        // 将原矩阵的元素按顺时针方向旋转 90 度填充到临时矩阵中
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                // 对于位置 (i, j),旋转后的位置是 (j, n-1-i)
                temp[j][n - 1 - i] = matrix[i][j];
            }
        }

        // 将临时矩阵的内容复制回原矩阵
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = temp[i][j];
            }
        }
    }
}

法二:原地旋转

public class Method02 {
    public void rotate(int[][] matrix) {
        // 获取矩阵的大小 n
        int n = matrix.length;

        // 对矩阵的层进行旋转,遍历前半部分的行数
        for (int i = 0; i < n / 2; i++) {
            // 遍历当前层的元素(为了完美旋转,每层需要处理的元素是当前行的一半)
            for (int j = 0; j < (n + 1) / 2; j++) {
                // 保存当前元素
                int temp = matrix[i][j];

                // 进行四个位置之间的元素交换
                // 当前位置 (i, j) 变为 (n - 1 - j, i)
                matrix[i][j] = matrix[n - 1 - j][i];

                // (n - 1 - j, i) 变为 (n - 1 - i, n - 1 - j)
                matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j];

                // (n - 1 - i, n - 1 - j) 变为 (j, n - 1 - i)
                matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i];

                // (j, n - 1 - i) 变为原来的 (i, j)
                matrix[j][n - 1 - i] = temp;
            }
        }
    }
}

leetcode8. 字符串转换整数 (atoi)

8. 字符串转换整数 (atoi)icon-default.png?t=O83Ahttps://leetcode.cn/problems/string-to-integer-atoi/

法一:模拟

public class Method01 {
    public int myAtoi(String s) {
        // 将输入字符串去除首尾空格,并转换为字符数组
        char[] chars = s.trim().toCharArray();

        // 如果字符数组为空,返回 0
        if (chars.length == 0) {
            return 0;
        }

        // 初始化符号(默认为正数)和结果变量
        int sign = 1;
        int result = 0;
        int i = 0;

        // 检查符号,并更新 sign 和 i
        if (chars[i] == '+') {
            i++; // 正号,继续处理
        } else if (chars[i] == '-') {
            sign = -1; // 负号,更新符号为 -1
            i++; // 移动到下一个字符
        }

        // 遍历字符数组,构建数字
        for (; i < chars.length; i++) {
            // 如果当前字符不是数字,则停止解析
            if (chars[i] < '0' || chars[i] > '9') {
                break;
            }

            // 检查是否会出现整数溢出
            if (result > Integer.MAX_VALUE / 10 ||
                    (result == Integer.MAX_VALUE / 10 && chars[i] > '7')) {
                // 根据符号返回对应的最大或最小值
                if (sign == 1) {
                    return Integer.MAX_VALUE; // 超出最大值,返回最大值
                } else {
                    return Integer.MIN_VALUE; // 超出最小值,返回最小值
                }
            }

            // 更新结果:将当前数字加入到结果中
            result = result * 10 + (chars[i] - '0');
        }
        // 返回结果乘以符号
        return sign * result;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值