11天刷完《剑指Offer》/ Day6:第50~54题

今天做上5道数组、字符的题,上午搞定!

T50. 数组中重复的数字

  • 题目描述

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

  • 解题思路
    我开始想的笨办法,硬着头皮改出错的思路(想东西总是乱),总算通过了…
public class Solution {
    // Parameters:
    //    numbers:     an array of integers
    //    length:      the length of array numbers
    //    duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
    //                  Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
    //    这里要特别注意~返回任意重复的一个,赋值duplication[0]
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    public boolean duplicate(int numbers[],int length,int [] duplication) {
  
         if(numbers == null || length == 0){
            return false;//注意题目要求,返回的是Boolean
        }
       
       for(int tem:numbers){
           int count=0;//位置在循环里,每个元素重新从0计数
            for(int i=0;i<length;i++){
               if(tem==numbers[i]) 
               count++;
                if(count>1) 
                 { duplication[0]=tem;
                   return true;}//括起来
           }
       }
    return false;}
}
                  *其他办法值得学习:*

排序

时间复杂度:O(nlogn)

将输入数组排序,再判断相邻位置是否存在相同数字,如果存在,对 duplication 赋值返回,否则继续比较

import java.util.*;
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers == null || length == 0){
            return false;
        }
        Arrays.sort(numbers);
        for(int i=0;i<length-1;i++){
            if(numbers[i] == numbers[i+1]){
                duplication[0] = numbers[i];
                return true;
            }
        }
        return false;
    }
}

哈希表

时间复杂度:O(n)
利用 HashSet 解决,从头到尾扫描数组,每次扫描到一个数,判断当前数是否存在 HashSet 中,如果存在,则重复,对
duplication 赋值返回,否则将该数加入到 HashSet 中

import java.util.*;
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        Set<Integer> set = new HashSet<>();
        for(int i =0 ;i<length;i++){
            if(set.contains(numbers[i])){
                duplication[0] = numbers[i];
                return true;
            }else{
                set.add(numbers[i]);
            }
        }
        return false;
    }
}

T51. 构建乘积数组

  • 题目描述

给定一个数组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]。不能使用除法。

  • 解题思路
import java.util.ArrayList;
public class Solution {
    public int[] multiply(int[] A) {
     if (A == null || A.length == 0) {
            return A;
        }
       int[] B= new int[A.length];
       B[0]=1;
        for(int i=1; i<A.length; i++){
            B[i]=B[i-1]*A[i-1];
        }
        int tem=1;
        for(int j=A.length-2;j>=0;j--){
            tem *= A[j+1];//每次都加紧靠后的一个数,tem更新为j后面的所有数积
            B[j] *= tem;//后一半乘前一半的积
        }
        return B;
    }
}

T52. 正则表达式匹配!

  • 题目描述

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

解题思路

T53. 表示数值的字符串

  • 题目描述

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

  • 解题思路
链接:https://www.nowcoder.com/questionTerminal/6f8c901d091949a5837e24bb82a731f2?answerType=1&f=discussion
来源:牛客网

正则表达式容易疏忽的地方:
1.底数不为空。如e8不是数字。
2.数字整数部分小数部分不能同时为空。如.不是数字。

public class Solution {
    public boolean isNumeric(char[] str) {
       法一: String s=String.valueOf(str);
             return s.matches("[\\+\\-]?(\\d*\\.\\d+|\\d+\\.?)([eE][\\+\\-]?\\d+)?");
		或者
	   法二:  String pattern = "^[-+]?\\d*(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?$";
               String s = new String(str);
               return Pattern.matches(pattern,s);
    }
}

T54. 字符流中第一个不重复的字符!

  • 题目描述

请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
(如果当前字符流没有存在出现一次的字符,返回#字符。)

  • 解题思路
    for循环的思路可以,不过这题要学习更简便的方法
public class Solution {
    int count[]=new int[256];
    //Insert one char from stringstream
    int index=1;
    public void Insert(char ch)
    {
        if(count[ch]==0){
          count[ch]=index++; 
        }
        else{
            count[ch]=-1;
        }
    }
  //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    {
        int temp=Integer.MAX_VALUE;
        char ch='#';
        for(int i=0;i<256;i++){
            if(count[i]!=0&&count[i]!=-1&&count[i]<temp){
                temp=count[i];
                ch=(char)i;
            }
        }
        return ch;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值