今天做上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;
}
}