Leetcode算法题笔记(4)

1. 字符串数字相加

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
在这里插入图片描述

解法一

因为是字符串数字,如果字符串太长,可能直接导致int或long溢出。因此需要用竖式计算,用数组计算每位相乘得到的结果,可以先采用累加的方式,最后再统一进位计算。
例如:789 * 6 = 【42,48,54】,最后再统一进位,【4,7,3,4】

class Solution {
    public String multiply(String num1, String num2) {
        int len1 = num1.length();
        int len2 = num2.length();
        if(num1.equals("0") || num2.equals("0")) return "0";
        int[] result = new int[len1+len2];
        //每个槽中进行累加
        for(int i = len1-1; i >= 0; i-- ){
            for(int j = len2-1; j >= 0 ; j--){
                result[j+i+1] += (num1.charAt(i) - '0')*(num2.charAt(j) - '0');//注意j+i+1才是index
            }
        }
        //进行进位计算
        int count = 0;
        for(int i = len1+len2-1; i >= 0; i--){
            if(result[i] + count >= 10){
                result[i] += count;//进位
                count = result[i] / 10;
                result[i] = result[i] % 10;
            }else{
                result[i] += count;
                count = 0;
            }
        }
        //转换成字符串
        StringBuilder sb = new StringBuilder();
        boolean flag = false;
        for(int i = 0; i < len1+len2; i++){
            if( !flag && result[i] > 0){
                flag = true;
            }
            if(flag){
                sb.append(result[i]);
            }
        }
        return sb.toString();
        
    }
}

2. Z字形变换

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);
在这里插入图片描述

解法一

维持一个StringBuilder数组,遍历字符串,首先从上到下依次放入字符到StringBuilder中,当字符串索引到底时(numRows)则开始反向,从下到上放置字符到StringBuilder的尾部,如此反复即可。

abcdefghi  3
a   e   i
b d f h
c   g
class Solution {
    public String convert(String s, int numRows) {
        if(numRows == 1) return s;
        StringBuilder[] sarr = new StringBuilder[numRows];
        for(int i = 0; i < numRows ; i++){
            sarr[i] = new StringBuilder();
        }
        int index = 0;
        boolean direct = false;
        int len = s.length();
        for(int i = 0; i < len; i++){
            sarr[index].append(s.charAt(i));
            if(!direct){//反向
                if(index == numRows - 1){
                    direct = true;
                    index = numRows - 2;
                }else{
                    index++;
                }
            }else{//反向
                if(index == 0){
                    direct = false;
                    index = 1;
                }else{
                    index--;
                }
            }
        }
        StringBuilder result = new StringBuilder();
        for(StringBuilder sb : sarr){
            result.append(sb);
        }
        return result.toString();
    }
}

3. 整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

解法一

利用取余和除法,依次取出最后一位数,然后与新数相加,每次新数都要乘以10。注意溢出问题。
在这里插入图片描述两边都除以10,即可得到新的判断式,且保证中间值不溢出32位数范围

123
3
310 + 2
(3
10+2)* 10 + 1 = 321

class Solution {
    public int reverse(int x) {
        int tmp = 0;
        int result = 0;
        while(x != 0){
            if(result < Integer.MIN_VALUE / 10 || result > Integer.MAX_VALUE/10) return 0;
            tmp = x % 10;
            x = x / 10;
            result = result*10 + tmp;
        }
        return result;
    }
}

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

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数。

函数 myAtoi(string s) 的算法如下:

空格:读入字符串并丢弃无用的前导空格(" ")
符号:检查下一个字符(假设还未到字符末尾)为 ‘-’ 还是 ‘+’。如果两者都不存在,则假定结果为正。
转换:通过跳过前置零来读取该整数,直到遇到非数字字符或到达字符串的结尾。如果没有读取数字,则结果为0。
舍入:如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被舍入为 −231 ,大于 231 − 1 的整数应该被舍入为 231 − 1 。
返回整数作为最终结果。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解题一

这题最主要是要读懂题意:遇到空格就跳过,遇到数字就开始计数,遇到-+就开始计数,如果空格-+排除后计数前遇到其他字符,则返回0;否则直接开始计数。计数时需要考虑之前的正负号。如果计数后遇到数字之外的其他字符,则直接返回结果。如果数字超过32位有符号整数的范围,则返回对应的边界值。

class Solution {
    public int myAtoi(String s) {
        if(s.equals("")) return 0;
        //首先去除空格
        int index = 0;
        while(index < s.length() && s.charAt(index) == ' ') index++;
        if(index == s.length()) return 0;
        int sign = 1;//正负标志位
        if(s.charAt(index) == '-'){
            sign = -1;
            index++;
        }else if(Character.isLetter(s.charAt(index))){
            return 0;
        }else if(s.charAt(index) == '+'){
            index++;
        }
        long result = 0;
        for(int i = index ; i < s.length(); i++){
            if(!Character.isDigit(s.charAt(i))){
                return (int)result;
            }
            result = result*10 + sign*(s.charAt(i) - '0');
            if(result > Integer.MAX_VALUE ) return Integer.MAX_VALUE;
            if(result < Integer.MIN_VALUE) return Integer.MIN_VALUE;
        }
        return (int)result;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值