剑指offer(48-53)

第48题

题目描述: 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

思路分析:
1.字符串的首位可能有符号,首先需要判断是否有符号,并且记录符号的类型;
2.根据是否存在符号位来标记字符串的起始位;
3.依次将每个字符转为数字(取出字符和0作减法),拼接到结果中;

代码如下:

public class Solution {
    public int StrToInt(String str) {
        if(str.length() == 0)
            return 0;
        int flag = 0;
        //第一个符号是+
        if(str.charAt(0) == '+')
            flag = 1;
        //第一个符号是-
        else if(str.charAt(0) == '-')
            flag = 2;
        //有符号则第二个数开始,没有则默认正数
        int start = flag > 0 ? 1 : 0;
        //用long类型存储最终值
        long res = 0;
        while(start < str.length()){
            //如果有一位不是数字,直接返回0
            if(str.charAt(start) > '9' || str.charAt(start) < '0')
                return 0;
            //拼接数字,通过字符和0作减法将字符转为数字
            res = res * 10 + (str.charAt(start) - '0');
            start ++;
        }
        return flag == 2 ? -(int)res : (int)res;
    }
}

第49题

题目描述: 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

思路分析: 因为数字的范围是0到n-1,n为数组的长度。所以我们可以定义一个长度为n的数组用于记录对应数字出现的次数,数组的下标就是对应的数字,对应下标下的数组值就是数组出现的次数。

代码如下:

public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        
        if(length==0||numbers==null){
            return false;
        }
        
        //用于记录每个数出现的次数
        int[] array = new int[length];
        
        //记录每个数出现的次数,数组的下标就是对应的数,对应位置数组的值就是数出现的次数
        for(int i=0;i<length;i++){
            array[numbers[i]]++;
        }
        
        for(int i=0;i<length;i++){
            if(array[i]>1){
                duplication[0] = i;
                return true;
            }
        }
        return false;
    }
}

第50题

题目描述: 给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2];)

思路分析: 简单来说,就是B[i]的值为A数组中除了A[i]以外其余位置的值相乘,但是不能使用除法。下面借鉴了一下剑指offer的思路,主要是自己要分析清楚数组下标的关系。
在这里插入图片描述
代码如下:

public class Solution {
    public int[] multiply(int[] A) {
        int length = A.length;
        int[] B = new int[length];
        if(length!=0){
            B[0] = 1;
            //上半部分
            for(int i =1;i<length;i++){
                B[i] = A[i-1]*B[i-1];
            }
            //下半部分
            int temp = 1;
            for(int j = length-2;j>=0;j--){
                temp = temp*A[j+1];
                B[j] = B[j]*temp;
            }
        }
        return B;
    }
}

第51题

题目描述: 请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配。

思路分析: 分为两种情况:当前模式串的后一位是星号()和不是星号;
是星号: 1.模式串当前位置的值能和Str匹配上,如::a
bb与abb、.bb和abb;
2.模式串当前位置的值能和Str匹配不上,如:a
bbb 与bbb;

不是星号:那么判断模式串当前位置的值是不是和Str当前位置值相等;

此题使用两个索引分别指向模式串和字符串Str的当前比较位置。

代码如下:

public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        //参数1代表需要匹配的字符串
        //参数2是正则表达式
        if(str == null || pattern == null){
            return false;
        }
        
        int strIndex = 0;
        int patternIndex = 0;
        return matchCore(str,0,pattern,0);
    }
    public boolean matchCore(char[] str, int strIndex, char[] pattern, int patternIndex){
        //1.strIndex到尾且patternIndex到尾
        if(strIndex == str.length && patternIndex == pattern.length){
            return true;
        }
        //2.strIndex没到尾且patternIndex到尾
        if(strIndex != str.length && patternIndex == pattern.length){
            return false;
        }
        
        //模式第2个是*
        if(patternIndex + 1 < pattern.length && pattern[patternIndex+1] == '*'){
             //1.字符串第1个跟模式第1个匹配(可能是字符 也可能是通配符)
            if((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (strIndex != str.length && pattern[patternIndex] == '.')){
                return matchCore(str,strIndex+1,pattern,patternIndex)
                    || matchCore(str,strIndex,pattern,patternIndex+2)
                    || matchCore(str,strIndex+1,pattern,patternIndex+1);
            }else{
                return matchCore(str,strIndex,pattern,patternIndex+2);
            }
        }
        //模式第2个不是*,但是字符串第1个跟模式第1个匹配(相同或者是通配符),则都后移1位,否则直接返回false
        if ((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)) {
            return matchCore(str, strIndex + 1, pattern, patternIndex + 1);
        }
        return false;
    }
}

第52题

题目描述: 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。

代码如下:

public class Solution {
    public boolean isNumeric(char[] str) {
        if (str == null || str.length == 0)
            return false;
        return new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?");
    }
}

第53题

题目描述: 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

思路分析: 涉及到字符出现的次数时,我们一般需要容器来保存它出现的次数。

代码如下:

import java.util.*;
public class Solution {
    //存储次数
    HashMap<Character,Integer> map = new HashMap<>();
    //存储顺序
    ArrayList<Character> list = new ArrayList<>(); 
    
    //Insert one char from stringstream
    public void Insert(char ch)
    {
        if(map.containsKey(ch)){
            map.put(ch,map.get(ch)+1);
        }else{
            map.put(ch,1);
        }
        //添加到链表中
        list.add(ch);
    }
    //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    {
        char ch = '#';
        for(char c:list){
            if(map.get(c)==1){
                ch = c;
                //找到第一个就返回
                break;
            }
        }
        return ch;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值