412.Fizz Buzz
题解:彻底的水题…3的倍数 5的倍数…
class Solution {
List<String> list;
public List<String> fizzBuzz(int n) {
list = new ArrayList<>();
for(int i=1;i<=n;i++){
boolean flag1 = i%5==0?true:false;
boolean flag2 = i%3==0?true:false;
if(flag1&&flag2){
list.add("FizzBuzz");
continue;
}
if(flag1){
list.add("Buzz");
continue;
}
if(flag2){
list.add("Fizz");
continue;
}
list.add(String.valueOf(i));
}
return list;
}
}
1002.查找常用字符
题解:题目说的有点不明不白了 直接打个比方吧
示例 1中第一个字符串有一个e 第二个字符串也有一个 第三个字符串也有一个e 所以list就添加了一个e 同理这三个字符串都有两个l 所以添加两个l到list中 所以答案就是ell
示例 2 c就不说了,说下o 这就是题意上说的那个了 第一个字符串有两个o 第二个字符串有一个o 第三个字符串有两个o 那么最后只能添加一个o(最小)
class Solution {
List<String> list;
int [] [] nums;
public List<String> commonChars(String[] A) {
list = new ArrayList<>();
nums = new int[A.length][26];
for(int i=0;i<A.length;i++){
String str = A[i];
for(int j=0;j<str.length();j++){
nums[i][str.charAt(j)-97]++;
}
}
for(int i=0;i<26;i++){
boolean flag = true;
int init = nums[0][i];
for(int j=1;j<nums.length;j++){
if(nums[j][i]==0){
flag = false;
break;
}else{
init = Math.min(init,nums[j][i]);
}
}
if(flag) {
for (int k = 0; k < init; k++) {
list.add(String.valueOf((char)(i+97)));
}
}
}
return list;
}
}
27.移除元素
题解:题目给出了提示 只能在原地修改数组 返回移除val数后nums的length,就一个for遍历 如果和给定的val不等 就从第0位开始覆盖 这样这题就解决了
class Solution {
public int removeElement(int[] nums, int val) {
int length = 0;
for(int i=0;i<nums.length;i++){
if(nums[i]!=val){
nums[length++]=nums[i];
}
}
return length;
}
}
788.旋转数字
题解:经过模拟当数字符合以下两种情况才能是好数
- 该数不能含有翻转后不是数字的数 即3,4,7
- 得含有至少一个翻转后是数字,且翻转后的数字不是本身的数
class Solution {
int [] flag ;
public int rotatedDigits(int N) {
int result = 0;
init();
for(int i=1;i<=N;i++){
String str = String.valueOf(i);
boolean Fn1 = false;//查询是否含有翻转不是数字的数
boolean Fn2 = true;//是否全为翻转是自己的数字的数
for(int j=0;j<str.length();j++){
int num = flag[str.charAt(j)-'0'];
if(num==-1){
Fn1 = true;
break;
}
else if(num==1){
Fn2 = false;
}
}
if(!Fn1&&!Fn2){
result++;
}
}
return result;
}
private void init(){
flag = new int[10];
flag[2]=1;
flag[5]=1;
flag[6]=1;
flag[9]=1;
flag[3]=-1;
flag[4]=-1;
flag[7]=-1;
}
}
202.快乐数
题解:其实就是一个简单的取各个位求平方和循环下去是否会求出1 开个集合去记录是否出现相同的平方和 一旦出现相同的平方和就说明原数不是快乐数
class Solution {
public boolean isHappy(int n) {
boolean flag = false;
List<Integer> list = new ArrayList<>();
int sum;
for(;;){
sum=0;
while(n>0){
int w = n%10;
sum+=w*w;
n/=10;
}
if(sum==1){
flag=true;
break;
}
if(list.contains(sum)){
break;
}
list.add(sum);
n=sum;
}
return flag;
}
}
917.仅仅反转字母
题解:就是对字符串进行操作,从开头遍历一旦遇到字母就进行while操作,倒起查询字符串是否是字母 是字母就插到该位置
class Solution {
public String reverseOnlyLetters(String S) {
char [] str1 = S.toCharArray();
int len = str1.length-1;
for(int i=0;i<str1.length;i++){
if(isZiMu(str1[i])){
while(!isZiMu(S.charAt(len))){
len--;
}
str1[i]=S.charAt(len);
len--;
}
}
return String.valueOf(str1);
}
private boolean isZiMu(char word){
if((word>='a'&&word<='z')||(word>='A'&&word<='Z')){
return true;
}
return false;
}
}
976.三角形的最大周长
题解:本题主要考查组成三角形的条件 任意两边之和大于第三边并且任意两边之差小于第三边 尽然要求最大周长 所以先排个序(数组长度为10000 用快排没问题)
class Solution {
public int largestPerimeter(int[] A) {
int c = 0;
Arrays.sort(A);
for(int i=A.length-1;i>=2;i--){
if(isSan(A[i],A[i-1],A[i-2])){
c=A[i]+A[i-1]+A[i-2];
break;
}
}
return c;
}
private boolean isSan(int i, int j, int u) {
if(((i+j)>u)&&((i-j)<u)){
return true;
}
return false;
}
}
415.字符串相加
题解:本题主要考察大数加法 其实大数加法不难 大数乘法难点 说下我自己的思路 先获取两个字符串最后的标记 用while循环相加 两个字符串相同位的数相加 大于10小于10进行操作 然后把处理的数添加到StringBuilder中 因为最后是倒起的 所以来个反转
class Solution {
public String addStrings(String num1, String num2) {
int i = num1.length()-1;
int j = num2.length()-1;
StringBuilder sb = new StringBuilder();//字符串操作用StringBuilder速度快
int sum,x=0;
while(i>=0||j>=0){//这样写主要不清楚两个字符串的长度大小
int n = i>=0?num1.charAt(i)-'0':0;
int m = j>=0?num2.charAt(j)-'0':0;
sum=n+m+x;//当前位置
if(sum>=10){
x=sum/10;//求进位
sum%=10;//当前位相加处理完后的数
}else{//没有大于等于10 进位就变成0
x=0;
}
sb.append(sum);
i--;
j--;
}
if(x!=0){//进位
sb.append(x);
}
return sb.reverse().toString();
}
}
628.三个数的最大乘积
题解:这题纯粹考的就是数学知识 首先长度不长 可以直接排个序 然后在判断一些特定的数组
- 数组全<=0或者全为>=0
- 数组首两个为负数(负负得正 三个负数直接不用管)且乘积大于数组倒数第三个和第二个的乘积
- 其他情况
class Solution {
public int maximumProduct(int[] nums) {
Arrays.sort(nums);
if(nums[nums.length-1]<=0||nums[0]>=0){
return nums[nums.length-1]*nums[nums.length-2]*nums[nums.length-3];
}
if(nums[0]*nums[1]>nums[nums.length-3]*nums[nums.length-2]){
return nums[0]*nums[1]*nums[nums.length-1];
}
return nums[nums.length-1]*nums[nums.length-2]*nums[nums.length-3];
}
}
88.合并两个有序数组
题解:直接一个for循环赋值 之后来个排序
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
for(int i=m;i<m+n;i++){
nums1[i]=nums2[i-m];
}
Arrays.sort(nums1);
}
}
326.3的幂
题解:有两种解法,如下
- 第一种解法就是打表 因为给的数字不会超过int 所以就很简单
- 第二种解法就是正常做法了
class Solution {//打表
List<Integer> list = new ArrayList<>();
public boolean isPowerOfThree(int n) {
init();
if(list.contains(n)){
return true;
}
return false;
}
private void init() {
for(int i=1;i>0;i*=3){// 超过int就负数了
list.add(i);
}
}
}
class Solution {
public boolean isPowerOfThree(int n) {
if(n<1){
return false;
}
while(n>1){
if(n%3!=0){
return false;
}
n/=3;
}
return true;
}
}
367.有效的完全平方数
题解:还是有两种解法,如下
- 打表,和上面一样
- 二分
class Solution {//打表效率好像不是很高
List<Integer> list = new ArrayList<>();
public boolean isPerfectSquare(int num) {
init();
if(list.contains(num)){
return true;
}
return false;
}
private void init(){
int num=1;
for(int i=1;num>0;i++){
num = i * i;
list.add(num);
}
}
}
class Solution{
public boolean isPerfectSquare(int num) {
long l = 0,r=num;
while(l<=r){
long n = l + (r-l)/2;
if(n*n==num)
return true;
else if(n*n<num)
l = n + 1;
else
r = n - 1;
}
return false;
}
}
26.删除排序数组中的重复项
题解:根据题意 只能用一个for来解决这道题 其实和上次做的那道差不多 因为是已经排个序的数组了 就是找到和当前值不等的值覆盖原数组
class Solution {
public int removeDuplicates(int[] nums) {
if(nums.length==0){
return 0;
}
int len = 1;
int num = nums[0];
for(int i=1;i<nums.length;i++){
int n = nums[i];
if(n!=num){
nums[len++]=n;
num=n;
}
}
return len;
}
}
231.2的幂
题解:普通解法,和3的幂一样的方法
class Solution {
public boolean isPowerOfTwo(int n) {
if(n<1){
return false;
}
while(n>1){
if(n%2!=0){
return false;
}
n/=2;
}
return true;
}
}
公式解法
class Solution {
public boolean isPowerOfTwo(int n) {
if(n <= 0) return false;
return (n&(n-1))==0;
}
}
35.搜索插入位置
题解:给题目补充下 不仅是排个序的 而且还是个升序排列的数组 看到排个序的数组查找某个数要条件反射的想到二分查找 这题就多了一个地方 可能查不到 就返回对应索引就行了
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0,right = nums.length-1;
int mid = 0;
while(left<right){//注意为什么不加等于 加了==边界情况下left right会超出数组 这里不加等于下边会处理的
mid = (left+right)/2;
if(nums[mid]==target){
return mid;
}
else if(nums[mid]<target){
left = mid + 1;
}else{
right = mid - 1;
}
}
if(target<=nums[left]){//这个数小于当前这个数 说明会在这个位置插入这个数 下同
return left;
}
else{
return left+1;
}
}
}
66.加一
题解:控制进位是这题最重要的
class Solution {
public int[] plusOne(int[] digits) {
int plus = 1;//要加的数默认为1
for(int i=digits.length-1;i>=0;i--){
int num = digits[i]+plus;
plus=num/10;//是否要进位
digits[i]=num%10;
if(plus==0){//不进位后边就不需要进位了直接跳出
break;
}
}
if(plus!=0){//如果要加的数不为0 说明遇到了99+1这种情况
int [] results = new int[digits.length+1];//新开一个比原数组长一位的数组
results[0]=plus;
System.arraycopy(digits,0,results,1,digits.length);//将digits数组从索引为0的元素开始 复制到数组results里的索引为1的位置 复制的元素个数为digits.length
return results;
}
return digits;
}
}
374.猜数字大小
题解:明显采用二分法
public class Solution extends GuessGame {
public int guessNumber(int n) {
int left = 1,right = n;
while(left<=right){
int mid = left +(right-left)/ 2;//防止溢出(left+right)/2
if(guess(mid)==0){
return mid;
}else if(guess(mid)==-1){//你猜的数大了
right=mid-1;
}else if(guess(mid)==1){//你猜的数小了
left=mid+1;
}
}
return -1;
}
}
7.整数反转
题解:这题有两种解法 一种转成字符串进行处理 一种直接数字处理
- 字符串处理
class Solution {
private final int LEFT = -2147483648;
private final int RIGHT = 2147483647;
public int reverse(int x) {
long result = 0;
if(x==0){
return 0;
}
if(x>0) {
StringBuilder sb = new StringBuilder(String.valueOf(x));
sb.reverse();
result = Long.valueOf(sb.toString());
}
if(x<0){
int len = String.valueOf(x).length();
StringBuilder sb = new StringBuilder(String.valueOf(x).substring(1,len));
sb.reverse();
result = - Long.valueOf(sb.toString());
}
if(result<LEFT||result>RIGHT){
return 0;
}
return (int)result;
}
}
- 数字直接处理
class Solution {
private final int LEFT = -2147483648;
private final int RIGHT = 2147483647;
public int reverse(int x) {
long result = 0;
boolean flag = true;
if(x==0){
return 0;
}
if(x<0){
flag = false;
x=-x;
}
while(x>0){
int wei = x%10;
result = result*10+wei;
x/=10;
}
if(!isInt(result)){
return 0;
}
return flag==true?(int)result:-(int)result;
}
private boolean isInt(long result) {
if(result<LEFT||result>RIGHT){
return false;
}
return true;
}
}
137.只出现一次的数字II
题解:线性时间不清楚 只知道要用二进制 等有空看看 非线性时间就先排个序在判断了
class Solution {
public int singleNumber(int[] nums) {
int result = 0;
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(i!=0&&nums[i]==nums[i-1]){
continue;
}
if(i!=nums.length-1&&nums[i]==nums[i+1]){
continue;
}
result = nums[i];
break;
}
return result;
}
}
204.计数质数
题解:用普通方法不行 要超时 必须用线性筛来解决
class Solution {
int [] prime;
boolean [] flags;
public int countPrimes(int n) {
prime = new int[n];
flags = new boolean[n];
int count = 0;
for(int i=2;i<n;i++){
if(!flags[i]){
prime[count++]=i;
}
for(int j=0;j<count&&i*prime[j]<n;j++){
flags[i*prime[j]]=true;
if(i%prime[j]==0){
break;
}
}
}
return count;
}
}
342.4的幂
题解:求某数的幂无非就是循环或者有技巧的做法 不多说了 水题
- 循环做法
class Solution {
public boolean isPowerOfFour(int num) {
if(num<=0){
return false;
}
boolean flag = true;
while(num>1){
if(num%4!=0){
flag=false;
break;
}
num/=4;
}
return flag;
}
}
- 技巧做法…不过不知道为什么用时比循环多点
class Solution {
public boolean isPowerOfFour(int num) {
return (((num - 1) & num)) == 0 && (num & 0x55555555) != 0;
}
}
925.长键按入
题解:特殊就不说了 从name开始总体循环 记录下当前的字符a 自循环 看看当前有多少个连着的相同字符 记下数目 之后再去typed用同样的方法去自循环 看看当前有多少个和字符a相同 最后比较下数目 如果数目大于等于name自循环的数目 继续循环 一旦小于name自循环的数目 直接返回false
class Solution {
boolean flag = true;
public boolean isLongPressedName(String name, String typed) {
if(name.length()==0&&typed.length()==0){
return true;
}
if(name.length()==0||typed.length()==0){
return false;
}
if(name.equals(typed)){
return true;
}
checkString(name,typed);
return flag;
}
private void checkString(String name, String typed){
int i=0,j=0;
while(i<name.length()){
char a = name.charAt(i);
int count1=1;
i++;
while(i<name.length()&&a==name.charAt(i)){
i++;
count1++;
}
int count2=0;
while(j<typed.length()&&a==typed.charAt(j)){
j++;
count2++;
}
if(count2<count1){
flag = false;
break;
}
}
}
}
442.数组中重复的数据
题解:没意思的一道水题 用map速度很慢就用数组来记录了
class Solution {
List<Integer> list;
int [] leng;
public List<Integer> findDuplicates(int[] nums) {
list = new ArrayList<>();
leng = new int[nums.length+1];
for(int i=0;i<nums.length;i++){
if(leng[nums[i]]==1){
list.add(nums[i]);
}
leng[nums[i]]++;
}
return list;
}
}
989.数组形式的整数加法
题解:这题没得其他方法 只能自己进行模拟 最好模拟那些进位多的
class Solution {
List<Integer> list;
public List<Integer> addToArrayForm(int[] A, int K) {
list = new ArrayList<>();
int plus = 0;
int index = A.length-1;
while(K>0&&index>=0){//不清楚K大还是A数组形成的数大
plus+=K%10;
plus=plusNum(A[index--],plus);;
K/=10;
}
while(K>0){//说明数组A形成的数小于K
plus+=K%10;
plus=plusNum(0,plus);
K/=10;
}
while(index>=0){//说明数组A形成的数大于K
plus=plusNum(A[index--],plus);;
}
if(plus!=0){
list.add(plus);
}
Collections.reverse(list);
return list;
}
private int plusNum(int i, int plus) {
int num = i+plus;
list.add(num%10);
return num/10;
}
}
290.单词模式
题解:明显用map 因为是双向的 所以只能a对应ok后 不能让b只向ook了 所以当key中不存在时 还要判断当下的当前循环的字符串在values中是否存在 存在就直接false了
class Solution {
public boolean wordPattern(String pattern, String str) {
boolean flag = true;
Map<Character,String> map = new HashMap<>();
String [] strs = str.split(" ");
if(strs.length!=pattern.length()){
flag = false;
return flag;
}
for(int i=0;i<pattern.length();i++){
char a = pattern.charAt(i);
if(!map.containsKey(a)){
if(map.values().contains(strs[i])){
flag = false;
break;
}else{
map.put(a,strs[i]);
}
}else{
if(!map.get(a).equals(strs[i])){
flag = false;
break;
}
}
}
return flag;
}
}
28.实现strStr()
题解:除开几个特殊情况 其他都循环判断和needle第一个字符是否相同 相同截取haystack,needle这长度的字符串 然后判断是否是相同的
class Solution {
public int strStr(String haystack, String needle) {
if(needle.length()==0){
return 0;
}
if(needle.length()>haystack.length()){
return -1;
}
if(needle.length()==haystack.length()&&needle.equals(haystack)){
return 0;
}
int result = -1;
char [] haystacks = haystack.toCharArray();
for(int i=0;i<haystacks.length;i++){
if(haystacks[i]==needle.charAt(0)){
if(i+needle.length()<=haystack.length()) {
String str = haystack.substring(i, i + needle.length());
if (str.equals(needle)) {
result = i;
break;
}
}
}
}
return result;
}
}
- 偷懒模式
class Solution {
public int strStr(String haystack, String needle) {
return haystack.indexOf(needle);
}
}
168.旋转数组
题解:新开一个数组 来记录 免得被覆盖掉 之后复制到原来数组中
class Solution {
public void rotate(int[] nums, int k) {
int [] numss = new int[nums.length];
for(int i=0;i<nums.length;i++){
numss[(i+k)%nums.length]=nums[i];
}
for(int i=0;i<nums.length;i++){
nums[i]=numss[i];
}
}
}
69.x的平方根
题解:有两分的思想 直接for循环 耗时间太久
class Solution {
public int mySqrt(int x) {
if(x<=3){
if(x==0){
return 0;
}else{
return 1;
}
}
long left = 2,right=x,result=0;
boolean flag1 = false,flag2=false;
while(left<=right){
long mid = left+(right-left)/2;
//System.out.println(mid);
long num = mid*mid;
if(num==x){
result = mid;
break;
}else if(num<x){
left = mid + 1;
long num1 = left*left;
if(num1>x){//要判断下一个数是不是大于x
result = mid;
break;
}
}else{
right = mid - 1;
long num2 = right*right;
if(num2<x){//要判断下一个数是不是小于x
result = mid-1;
break;
}
}
}
return (int)result;
}
}
744.寻找比目标字母大的最小字母
题解:寻找比目标字母大的最小字母,注意所给的字符数组是循环的 其实也就是初始化字符为第一个字符 当在有序的字符数组中找不到指定的字符 直接返回第一个字符就可以了
class Solution {
public char nextGreatestLetter(char[] letters, char target) {
char a = letters[0];
for(int i=0;i<letters.length;i++){
char letter = letters[i];
if(letter>target){
a = letter;
break;
}
}
return a;
}
}
345.反转字符串中的元音字母
题解:从开头遍历 找到是元音就从后边开始找事元音就交换 用while循环
class Solution {
public String reverseVowels(String s) {
char [] strs = s.toCharArray();
int index = 0,end=strs.length-1;
while(index<end){
if(isYuanYin(strs[index])){
while(!isYuanYin(strs[end])){
end--;
}
if(end<=index){
break;
}
char a = strs[end];
strs[end]=strs[index];
strs[index]=a;
end--;
}
index++;
}
return new String(strs);
}
private boolean isYuanYin(char str) {
if(str=='a'||str=='e'||str=='i'||str=='o'||str=='u'){
return true;
}
if(str=='A'||str=='E'||str=='I'||str=='O'||str=='U'){
return true;
}
return false;
}
}
704.二分查找
题解:二分查找模板 没什么要多说什么的
class Solution {
public int search(int[] nums, int target) {
int index = -1;
int left = 0,right = nums.length-1;
while(left<=right){
int mid = left + (right-left)/2;
if(nums[mid]==target){
index = mid;
break;
}else if(nums[mid]<target){
left = mid+1;
}else{
right = mid-1;
}
}
return index;
}
}
167.两数之和 II - 输入有序数组
题解:理解了二分查找 这题就简单多了 就用二分的思想来加两个数
//用双重for会超时在最后一个测试数据上
class Solution {
public int[] twoSum(int[] numbers, int target) {
int [] results = new int[2];
int left = 0,right=numbers.length-1;
while(left<right){
int num = numbers[left]+numbers[right];
if(num==target){
results[0]=left+1;
results[1]=right+1;
break;
}
else if(num<target){
left++;
}else{
right--;
}
}
return results;
}
}
506.相对名次
题解:用map来记录分数的下标 排个序 根据map记录的下标来记录名次
class Solution {
Map<Integer,Integer> map;
public String[] findRelativeRanks(int[] nums) {
map = new HashMap<>();
String [] results = new String[nums.length];
for(int i=0;i<nums.length;i++){
map.put(nums[i],i);
}
Arrays.sort(nums);
int score = 4;
for(int i=nums.length-1;i>=0;i--){
if(i==nums.length-1){
results[map.get(nums[i])]="Gold Medal";
}else if(i==nums.length-2){
results[map.get(nums[i])]="Silver Medal";
}else if(i==nums.length-3){
results[map.get(nums[i])]="Bronze Medal";
}else{
results[map.get(nums[i])]= String.valueOf(score);
score++;
}
}
return results;
}
}
38.报数
题解:可以采用打表法 这里我没用打表法 打表有点耗时
class Solution {
String [] results;
public String countAndSay(int n) {
init();
for(int i=2;i<=n;i++){
int num1 = results[i-1].charAt(0)-'0';
int count = 1;
StringBuilder sb = new StringBuilder();
for(int j=1;j<results[i-1].length();j++){
int num2 = results[i-1].charAt(j)-'0';
if(num1==num2){
count++;
}else{
sb.append(count);
count = 1;
sb.append(num1);
num1 = num2;
}
}
sb.append(count);
sb.append(num1);
results[i]=sb.toString();
}
return results[n];
}
private void init() {
results = new String[31];
results[1] = "1";
}
}
205.同构字符串
题解:用map来记录 条件:前后对应
class Solution {
Map<Character,Character> map;
public boolean isIsomorphic(String s, String t) {
boolean flag = true;
map = new HashMap<>();
for(int i=0;i<s.length();i++){
if(!map.containsKey(s.charAt(i))){
if(!map.values().contains(t.charAt(i))) {
map.put(s.charAt(i), t.charAt(i));
}
else{
flag = false;
break;
}
}else{
if(map.get(s.charAt(i))!=t.charAt(i)){
flag = false;
break;
}
}
}
return flag;
}
}
844.比较含退格的字符串
题解:倒起遍历字符串 记录#次数 遇到字母如果#次数为0就添加到 StringBuilder中 最后toString().equals一下来判断
class Solution {
public boolean backspaceCompare(String S, String T) {
boolean flag = true;
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
sb1=appendString(S);
sb2=appendString(T);
if(sb1.reverse().toString().equals(sb2.reverse().toString())){
return flag;
}else {
flag = false;
return flag;
}
}
private StringBuilder appendString(String s) {
int count = 0;
StringBuilder sb = new StringBuilder();
for(int i=s.length()-1;i>=0;i--){
if(s.charAt(i)=='#'){
count++;
}
else{
if(count==0){
sb.append(s.charAt(i));
}else{
count--;
}
}
}
return sb;
}
}
383.赎金信
题解:记录两个字符串字母出现次数 当notes[i]>magazines[i]就说明不能拼凑出来
class Solution {
int [] notes;
int [] magazines;
public boolean canConstruct(String ransomNote, String magazine) {
boolean flag = true;
notes = new int[26];
magazines = new int[26];
init(ransomNote,notes);
init(magazine,magazines);
for(int i=0;i<26;i++){
if(notes[i]>magazines[i]){
flag = false;
break;
}
}
return flag;
}
private void init(String s,int [] num){
for(char a:s.toCharArray()){
num[a-97]++;
}
}
}
387.字符串中的第一个唯一字符
- 傻瓜做法
- 还是像上题一样记录次数 另一个数组记录出现位置(主要记录出现一次那个字符的位置)
class Solution {
int [] nums;
int [] indexs;
public int firstUniqChar(String s) {
int index = -1;
nums = new int[26];
indexs = new int[26];
init(s);
for(int i=0;i<s.length();i++){
char a = s.charAt(i);
if(nums[a-97]==1){
index=indexs[a-97];
break;
}
}
return index;
}
private void init(String s){
for(int i=0;i<s.length();i++){
char a = s.charAt(i);
nums[a-97]++;
indexs[a-97]=i;
}
}
}
- 聪明做法
- 直接从a到z遍历,字符串中第一次出现位置和最后一次出现位置是否相同
class Solution {
public int firstUniqChar(String s) {
int index = -1;
for(char a='a';a<='z';a++){
int index1 = s.indexOf(a);
int index2 = s.lastIndexOf(a);
if(index1==index2&&index1!=-1){
if(index==-1){
index=999999999;
}
index = Math.min(index,index1);
}
}
return index;
}
}
819.最常见的单词
题解:用map来记录出现次数 用set来记录出现的字符串 set移除banned中包含的字符串
class Solution {
String [] paragraphs;
Map<String,Integer> map;
Set<String> set;
public String mostCommonWord(String paragraph, String[] banned) {
init(paragraph);
for(String str:paragraphs){
set.add(str);
map.putIfAbsent(str,0);
map.put(str,map.get(str)+1);
}
for(int i=0;i<banned.length;i++){
set.remove(banned[i]);
}
String maxs="";
int num = 0;
for(String str:set){
if(num<map.get(str)){
num=map.get(str);
maxs=str;
}
}
return maxs;
}
private void init(String paragraph){
map = new HashMap<>();
set = new HashSet<>();
paragraph = paragraph.replaceAll("[^a-zA-Z]"," ");
paragraphs = paragraph.toLowerCase().split("\\s+");
}
}
434.字符串中的单词数
题解:用空格切成字符串数组 遍历字符串数组 一旦长度为0 说明为空 不计其中
class Solution {
public int countSegments(String s) {
String [] strs = s.split(" ");
int count = 0;
for(String str:strs){
if(str.length()!=0){
count++;
}
}
return count;
}
}
58.最后一个单词的长度
题解
- 先考虑等于0情况 全是空格或者长度为0
- 其他就倒起遍历为空格且长度不为0就跳出
class Solution {
public int lengthOfLastWord(String s) {
if(s.length()==0||s.trim().length()==0){
return 0;
}
int len = 0;
for(int i=s.length()-1;i>=0;i--){
if(s.charAt(i)==' '){
if(len!=0) {
break;
}
continue;
}
len++;
}
return len;
}
}
172.阶乘后的零
题解
- 求阶乘所得数末尾有几个0
- 比如6! = 【1* 2* 3* 4* 5* 6】=120
- 其中只有2*5末尾才有0,所以就可以抛去其他数据 专门看2 5 以及其倍数 毕竟 4 * 25末尾也是0
- 比如10! = 【24568*10】
- 其中 4能拆成22 10能拆成25
- 所以10! = 【2*(22)5(23)(222)(2*5)】
- 一个2和一个5配对 就产生一个0 所以10!末尾2个0
- 2肯定比5多 所以只数5的个数就行了
public int trailingZeroes(int n) {
int result = 0;
while(n>=5){
result+=n/5;
n/=5;
}
return result;
}