文章目录

  • Day5.牛客网剑指offer 67题之43-54题
  • 43.左旋转字符串
  • 44.翻转单词顺序列
  • 45.扑克牌顺序
  • 46.孩子们的游戏
  • 47.求1+2+...+n
  • 48.不用加减乘除做加法
  • 49.把字符串转化为整数
  • 50.数组中重复的数字
  • 51.构建乘积数组
  • 52.正则表达式匹配
  • 53.表示数值的字符串
  • 54.字符流中第一个不重复的字符

Day5.牛客网剑指offer 67题之43-54题

仍然是早起的一天准备专业基础知识面试会场安排,不过今天工作量比较小,分配的软件工程课程面试只有两个人,听他们回答问题仿佛看到了两年那个不知所措的自己…后面两天就很忙了,争取明天把最后的题目刷完吧,今天的题有点像之前题目的进化版,所以还是要多想多写,自己之前看到题目就懵,主要还是很多结构用不熟练。

43.左旋转字符串

题目描述
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
思路左旋转其实可以分三步进行一个字符串的逆序

  1. abc→cba 得到cbaXYZdef
  2. XYZdef→fedZYX 得到cbafedZYX
  3. cbafedZYX→XYZdefabc 得到结果
public class Solution {public String LeftRotateString(String str,int n) {if(str.length()==0) return "";char[] cStr=str.toCharArray();reverse(cStr,0,n-1);reverse(cStr,n,str.length()-1);reverse(cStr,0,str.length()-1);return new String(cStr);}public void reverse(char []str,int start,int end){while(start<end){char temp=str[start];str[start]=str[end];str[end]=temp;start++;end--;}}
}

44.翻转单词顺序列

题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
思路
这一题跟上一题类似的思路,先把每个单词翻转,然后再翻转整个序列,这里就需要找好每一个单词的开头和结尾。

public class Solution {public String ReverseSentence(String str) {if(str.length()==0) return "";char[] cStr=str.toCharArray();int startIndex=0,endIndex=0;while(endIndex<=str.length()){//这里注意判定走到最后的条件,之前使用了endIndex<用例通不过if(endIndex==str.length()||cStr[endIndex]==' '){reverse(cStr,startIndex,endIndex-1);startIndex=endIndex+1;}endIndex++;}reverse(cStr,0,str.length()-1);return new String(cStr);}public void reverse(char[] str,int start,int end){while(start<end){char temp=str[start];str[start]=str[end];str[end]=temp;start++;end--;}}
}

45.扑克牌顺序

题目描述
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
思路
题目很长找关键信息,其实就是给定的一个数组里五张牌,能不能连成顺子。大小王(0)可以代替任何牌,如果有两张牌一样肯定不是癞子,两张牌之间的差值-1一定要在大王小王数量范围之内。

import java.util.Arrays;
public class Solution {public boolean isContinuous(int [] numbers) {if(numbers==null||numbers.length<5) return false;Arrays.sort(numbers);int wNum=0;//王牌for(int i=0;i<numbers.length;i++){if(numbers[i]==0)wNum++;}for(int i=wNum;i<numbers.length-1;i++){if(numbers[i]==numbers[i+1]&&numbers[i]!=0) return false;int temp=numbers[i+1]-1-numbers[i];if(temp>wNum) return false;wNum-=temp;}return true;}
}

46.孩子们的游戏

题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
如果没有小朋友,请返回-1
思路
约瑟夫环的思路,当然可以直接用数学方法解决,自己可以动手走一遍流程,其实我看了别人的思路我也讲不清楚。

public class Solution {public int LastRemaining_Solution(int n, int m) {if(n==0||m==0) return -1;int ans=0;for(int i=2;i<=n;i++){ans=(ans+m)%i;}return ans;}
}

47.求1+2+…+n

题目描述
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
思路
使用逻辑与或的方式得到退出递归条件即可

public class Solution {public int Sum_Solution(int n) {int sum=n;//n==0||(sum+=Sum_Solution(n-1))>0;boolean flag=(n>0)&&(sum+=Sum_Solution(n-1))>0;return sum;}
}

48.不用加减乘除做加法

题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
思路
位运算。

public class Solution {public int Add(int num1,int num2) {while(num2!=0){int temp=num1^num2;//求和num2=(num1&num2)<<1;//进位num1=temp;}return num1;}

49.把字符串转化为整数

题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
输入描述:
输入一个字符串,包括数字字母符号,可以为空
输出描述:
如果是合法的数值表达则返回该数字,否则返回0
思路
首先先判断第一个字符+,-号问题,然后后面的数正常转化(这里需要考虑溢出的问题)。
卡了很久啊,溢出值如何AC出来。。。-2147483649就输出不了,leetcode那里好像也有挺多思路的,不过说实话还是挺无语的。。
不考虑溢出(只通过85%)

 public int StrToInt(String str) {if(str.length() == 0) return 0;char[] chars = str.toCharArray();boolean isNegative = chars[0] == '-';//判断是否有负号int result = 0;for(int i = 0; i < chars.length; i ++) {if(i == 0 && (chars[i] == '+' || chars[i] == '-')) continue;//跳过正负号if(chars[i] < '0' || chars[i] > '9') return 0;result = result * 10 + (chars[i] - '0');}return isNegative ? -result : result;//三元}

考虑溢出
反正俩个都通过不了,测试用例已经超出long范围了…搜了一下好像是说python可以处理,会写python的就用python去AC吧。

public int StrToInt(String str) {if (str == null)return 0;int result = 0;boolean negative = false;//是否负数int i = 0, len = str.length();/*** limit 默认初始化为 负的 最大正整数 ,假如字符串表示的是正数* 那么result(在返回之前一直是负数形式)就必须和这个最大正数的负数来比较,* 判断是否溢出*/int limit = -Integer.MAX_VALUE;int multmin;int digit;if (len > 0) {char firstChar = str.charAt(0);//首先看第一位if (firstChar < '0') { // Possible leading "+" or "-"if (firstChar == '-') {negative = true;limit = Integer.MIN_VALUE;//在负号的情况下,判断溢出的值就变成了 整数的 最小负数了} else if (firstChar != '+')//第一位不是数字和-只能是+return 0;if (len == 1) // Cannot have lone "+" or "-"return 0;i++;}multmin = limit / 10;while (i < len) {// Accumulating negatively avoids surprises near MAX_VALUEdigit = str.charAt(i++)-'0';//char转intif (digit < 0 || digit > 9)//0到9以外的数字return 0;//判断溢出if (result < multmin) {return 0;}result *= 10;if (result < limit + digit) {return 0;}result -= digit;}} else {return 0;}//如果是正数就返回-result(result一直是负数)return negative ? result : -result;}

50.数组中重复的数字

题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路
其实看题目描述的话我觉得用HashSet完全是可以的,不过从代码结构来看的话,这个应该是判断是否有重复值吧,估计就是用计数排序的思想了,让每一个值与数组下标对应,不对应就交换他该到的位置。
也可以直接排序之后找重复,因为在代码里它说是可以返回任意一个重复值。
计数交换排序

public boolean duplicate(int numbers[],int length,int [] duplication) {int index = 0;while(index < length) {if(numbers[index] == index) {index ++;} else {int num = numbers[index];if(numbers[num] == num) {//存在重复duplication[0] = num;return true;} else {//不重复则将num交换到numbers[num]上int tmp = numbers[num];numbers[num] = num;numbers[index] = tmp;}}}return false;}

排序后比较

public boolean duplicate(int[] numbers, int length, int[] duplication) {//排序,找重复if(numbers == null || numbers.length == 0) {return false;}Arrays.sort(numbers);for(int i = 0; i < length - 1; i ++) {if(numbers[i + 1] == numbers[i]) {duplication[0] = numbers[i];return true;}}return false;}

51.构建乘积数组

题目描述
给定一个数组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[i]相乘,所以可以把所有对应的A[i]看成是1,此时会把数组B分成上下两部分三角区域,再分别进行连乘即可,图可以自己画一下,其中上部分没有B[n-1]计算,下部分没有B[0]计算。

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] = B[i-1] * A[i-1];}int temp = 1;//计算上三角for(int j = length-2; j >= 0; j--){temp *= A[j+1];B[j] *= temp;}}return B;}

52.正则表达式匹配

题目描述
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配
思路
正则表达式用到比较少,理解的也不是特别透彻,这里也是学习了别人的思路,主要还是细心,匹配好各种条件。

public boolean match(char[] str, char[] pattern) {if(str == null || pattern == null) return false;if(str.length == 0 && pattern.length == 0) return true;//都空,匹配成功if(str.length != 0 && pattern.length == 0) return false;//第一个非空,第二个空,匹配失败(相反是有可能成功的,例如"a*a*"可匹配成"")if(str.length == 0){if((pattern.length == 2 && pattern[1] == '*')){//特殊情况return true;}else {return false;}}return matchCore(str, 0, pattern, 0);}private boolean matchCore(char[] str, int sIndex, char[] pattern, int pIndex) {if(sIndex == str.length && pIndex == pattern.length) return true;if(sIndex != str.length && pIndex == pattern.length) return false;if((pIndex + 1) < pattern.length && pattern[pIndex + 1] == '*') {if((sIndex < str.length && str[sIndex] == pattern[pIndex]) || (pattern[pIndex] == '.' && sIndex < str.length)) {return matchCore(str, sIndex + 1, pattern, pIndex + 2) || matchCore(str, sIndex + 1, pattern, pIndex)|| matchCore(str, sIndex, pattern, pIndex + 2);}else{return matchCore(str, sIndex, pattern, pIndex + 2);}}if((sIndex < str.length && str[sIndex] == pattern[pIndex])|| (pattern[pIndex] == '.' && sIndex < str.length)) {return matchCore(str, sIndex + 1, pattern, pIndex + 1);}else{return false;}}

53.表示数值的字符串

题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。
思路
跟上一题类似,也是需要考虑匹配的所有情况,细心一点就好,尤其要注意符号跟小数点的匹配问题。

public boolean isNumeric(char[] str) {//分别需要判断e指数、符号和小数点是否符合要求boolean sign=false,decimal=false,e=false;for(int i=0;i<str.length;i++){if(str[i]=='e'||str[i]=='E'){if(e||i==str.length-1) return false;//e后面不能为空if(str[i-1]>'9'||str[i-1]<'0') return false;//e的前面必须为数字e=true;}else if(str[i]=='+'||str[i]=='-'){//符号要么在开头,要么前面必须跟eif(sign && str[i-1]!='e' && str[i-1]!='E') return false;if(!sign && i>0 && str[i-1]!='e' && str[i-1]!='E') return false;sign=true;}else if(str[i]=='.'){//小数点不能大于1个且不能在e后面且不能在末尾if(decimal||e||i==str.length-1) return false;decimal=true;}else if(str[i]>'9'||str[i]<'0')return false;}return true;}

也可以直接正则表达式匹配

public boolean isNumeric(char[] str) {return new String(str).matches("[\\+\\-]?\\d*(\\.\\d+)?([eE][\\+\\-]?\\d+)?");}

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

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

输出描述: 如果当前字符流没有存在出现一次的字符,返回#字符。

思路
这一题思路跟34题求第一个只出现一次的字符类似,只不过这里因为是需要实现字符流的输出,所以新加一个ArrayList进行元素存储。

import java.util.HashMap;
import java.util.ArrayList;
public class Solution {//Insert one char from stringstreamHashMap<Character,Integer> map=new HashMap<>();ArrayList<Character> list=new ArrayList<Character>();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 stringstreampublic char FirstAppearingOnce(){for(char key:list){if(map.get(key)==1)return key;}return '#';}
}

下一篇:牛客网剑指offer 67题之55-67题
上一篇:牛客网剑指offer 67题之33-42题

Day5.牛客网剑指offer 67题之43-54题(java代码)相关推荐

  1. 牛客网剑指offer编程实践1-10题

    牛客网剑指offer编程实践1-10题 1.二维数组中的查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这 ...

  2. Java算法:牛客网Java版剑指Offer全套算法面试题目整理及电子档,Java算法与数据结构面试题,面试刷题、背题必备!牛客网剑指offer

    剑指offer(java版) 牛客网Java版剑指Offer全套题目67道 资源来源于网络 目录 1.二维数组中的查找 2.替换空格 3.从尾到头打印链表 4.重建二叉树 5.用两个栈实现队列 6.旋 ...

  3. 《牛客网 剑指Offer前20题》

    <剑指Offer> 牛客网 前20道题 前言知识 面试题1:二维数组中的查找 面试题2:二维数组中的查找 面试题3:从头到尾打印链表 面试题4:重建二叉树 ***** 面试题5:两个栈实现 ...

  4. 牛客网剑指offer java 全部题解

    经过数月的努力,终于更完了牛客网的66道剑指offer,以下的顺序和大家在牛客网的顺序是一样的(排序也花了不少时间),希望对大家找工作/提高算法能力能起到些许帮助. 每天一道剑指offer-二维数组中 ...

  5. 牛客网剑指offer(Python版)

    剑指offer官网:  https://www.nowcoder.com/ta/coding-interviews 写在前面的话 刷剑指offer的时候只需要提交函数核心部分,但是在公司实际笔试时却需 ...

  6. 牛客网剑指offer——Java题解

    剑指offer JZ1 二维数组中的查找 题目描述 在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这 ...

  7. 牛客网剑指offer编程实践41-50题

    41.和为S的连续正数序列 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两 ...

  8. 牛客网剑指Offer C++题解

    [二维数组中的查找]:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是 ...

  9. 牛客网剑指offer编程实践51-66题

    51. 构建乘积数组 给定一个数组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].不 ...

最新文章

  1. [摘录]第8章 与非美国人谈判的技巧
  2. 加固工程验收规范50550_石家庄栾城县厂房梁柱加固施工队规范作业-建筑加固
  3. sqlserver中pivot的使用
  4. 爬虫笔记10Scrapy-框架
  5. iOS中UITextField的字数限制
  6. Opencv SVM demo
  7. socket io 不使用redis_Redis这么快,线程模型竟然是单线程
  8. Java集合之Hashtable源码分析
  9. “丑东西”,正在成为一门生意
  10. JDK 中的证书生成和管理工具 keytool
  11. 初步认识图像的直方图
  12. 网络教学的即时通讯视频
  13. These dependencies were not found:问题
  14. VxLAN技术基本原理
  15. 设置页眉为计算机网络,word文档设置页眉线如题,怎么设置上边的 – 手机爱问...
  16. 二月(不积跬步无以至千里)
  17. 算法笔记习题 7-1小节
  18. 核芯物联Command ‘cle‘ not found错误处理
  19. classnames库的简单使用
  20. 联想电脑thinkPad开机黑屏

热门文章

  1. 发布功能完成02《ivx低代码签到系统制作》
  2. topK问题分析与实现
  3. Hive自定义函数(字母大小写转换)
  4. SELinux权限问题解决
  5. ResNext架构解析:深度神经网络的聚合残差变换
  6. 关于搭建一个简易搭建网站的大概步骤
  7. 最热门的国人开发开源软件 TOP 50
  8. 表空间相关命令及查询SQL
  9. DNA-蛋白翻译过程的Python实现
  10. 如何对接payjs的个人微信扫码支付接口