classPeekingIteratorimplementsIterator<Integer>{
//通过原生的api明显是不能完成peek这个操作的,所以要自己用单独的方式实现//其次就是我不next的情况下,最多只能peek一次,也就是我只要存储一个数据就可以了,这个数据是前一个的//只要它不为0,那么就返回它,但只能使用一次privateIterator<Integer> iterator;privateint peekElement =0;// 0 代表无数据publicPeekingIterator(Iterator<Integer> iterator){
// initialize any member here.this.iterator = iterator;}// Returns the next element in the iteration without advancing the iterator.publicIntegerpeek(){
if(peekElement!=0)return peekElement;//peek可以无限用if(iterator.hasNext()) peekElement = iterator.next();return peekElement;}// hasNext() and next() should behave the same as in the Iterator interface.// Override them if needed.@OverridepublicIntegernext(){
int res =0;if(peekElement!=0||!iterator.hasNext()){
res = peekElement;
peekElement =0;//只能使用一次}else res = iterator.next();return res;}@OverridepublicbooleanhasNext(){
return iterator.hasNext()||peekElement!=0;//当peekElement不为0时,说明}}
10-06 lc414. 第三大的数
写的有点懵。。一直在想怎么写的更优雅,结果一直都不优雅
两种解法,都差不多
classSolution{
//需要是第三大的不同的数字,如果相同,则认为是一个//用三个变量来记录publicintthirdMax(int[] nums){
long first =Long.MIN_VALUE;long second =Long.MIN_VALUE;long third =Long.MIN_VALUE;//先从小数来更新,就会出错,所以从大数来看for(int num: nums){
long cur = num;if(cur>first){
//swaplong t = cur;
cur = first;
first = t;}elseif(cur==first)continue;if(cur>second){
//swaplong t = cur;
cur = second;
second = t;}elseif(cur==second)continue;if(cur>third){
//swaplong t = cur;
cur = third;
third = t;}}if(third!=Long.MIN_VALUE)return(int)third;return(int)first;}}
因为不能像go语言那样快速交换,所以这里写起来很丑,不然就三个swap,就很舒服了
还有一种下面的写法,稍微短一些,看起来也还好
classSolution{
publicintthirdMax(int[] nums){
long first =Long.MIN_VALUE;long second =Long.MIN_VALUE;long third =Long.MIN_VALUE;for(int num: nums){
if(num>first){
third = second;
second = first;
first = num;}elseif(num>second&&num<first){
third = second;
second = num;}elseif(num>third&&num<second) third = num;}return(int)(third ==Long.MIN_VALUE? first:third);}}
这里都通过long来解决边界,边界值太恶心了,要附加很多逻辑,不如用long
10-07 lc434. 字符串中的单词数
简单题,就是需要自己去实现split,来解决空格问题
classSolution{
//连续的不是空格的字符//测试用例太少了,只能试试了//"",",,,, a, eaefa"publicintcountSegments(String s){
s +=" ";char[] ss = s.toCharArray();int cnt =0;for(int i=0; i<ss.length; i++){
if(ss[i]==' '&&i>0&&ss[i-1]!=' ')
cnt++;}return cnt;}}
这里记录一个api,String s = new String(char[] chs, int offeset, int count), 这是从char数组中生成String的方法,很好用
其实这里的问题在于,生成了过多的String,对gc其实蛮有压力的
classSolution{
publicList<String>findRepeatedDnaSequences(String s){
Set<String> set =newHashSet<>();//存储出现元素Set<String> res =newHashSet<>();//存储结果元素char[] ss = s.toCharArray();for(int i=0; i<ss.length-9; i++){
String cur =newString(ss,i,10);if(set.contains(cur)) res.add(cur);
set.add(cur);}//set转listreturnnewArrayList<String>(res);}}
10-09 lc352. 将数据流变为多个不相交区间
这题很好,但是写题目的人很辣鸡,题意没写清楚,我真是服了
意思是,将连续的数字给写成一个区间
难点在于,需要不断的插入新的数,导致情况变化,所以每次进行统计
我这里是O(n2)方解法的,每次都是暴力解
classSummaryRanges{
//这题出的很垃圾,题目意思没有讲清楚,导致看了示例之后更懵了,搞不清楚是为啥//终于明白了,这题的意思是连续的进行合并成一个区间,不连续的单独作为一个区间//O(n2)暴力解,用什么数据结构来存储呢,能够o1的存,然后O(n)的取//直接用数组存储就好了,因为范围有限privateint[] vals;publicSummaryRanges(){
vals =newint[10001];}publicvoidaddNum(int val){
vals[val]=1;}publicint[][]getIntervals(){
List<int[]> list =newArrayList<>();int i =0;while(i<=10000){
while(i<=10000&&vals[i]==0) i++;if(i>10000)break;int[] cur =newint[2];
cur[0]= i;
cur[1]= i;while(i<=10000&&vals[i]!=0) i++;
cur[1]= i-1;
list.add(cur);}int[][] res =newint[list.size()][2];for(i=0; i<res.length; i++){
int[] cur = list.get(i);
res[i][0]= cur[0];
res[i][1]= cur[1];}return res;}}
10-10 lc441. 排列硬币
是一个简单题,反正就很简单
用求和公式来,首先找到平方数,向上取整,让后往下找,知道求和公式结果小于等于当前的n
因为这里数会越界,所以全程用long来进行处理,就能解决
同时,平方数离答案的距离已经很近了,这里就不用再用Ologn了,直接On往下遍历就行了
classSolution{
//最后一行可以不完整,而前面必须完整i行必须有i个//最简单的思路,这是一个累加和,直接从1一直加到大于这个数,然后返回前一个就可以,这样会超时//用求和公式来,(1+k)*k/2 = (k+k2)/2--> 2n的平方根,然后分别往下去找publicintarrangeCoins(int n){
long t =2*(long)n;long i =(long)Math.sqrt(t)+1;//向上取整,此时累加是大于2n的while(sum(i)>t) i--;return(int)i;}privatelongsum(long sqrt){
return(1+sqrt)*sqrt;}}