一、回文数判断
给你一个整数 x
,如果 x
是一个回文整数,返回 true
;否则,返回 false
。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
分析:
回文的话,首先想到的方法是通过调换字符顺序后比较原数值,如果相等则为回文,反之则不相等。但是时间复杂度比较高,且有可能出现值溢出的情况,于是参考别人解法:
(半数比较)
首先是通过简单语句可以筛选一些不是回文的数例如:”-123“或者个数为0的数。个位数为0的话,回文数是0开头,0开头的数只有0,于是可以简单排除。
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
之后,我们使用待判断数字不断对10取模,得到尾数组成回文数,在回文数的数字个数为奇数的情况下:直到回文数大于再对尾数取模判断两数是否相等
或者在回文的数字个数为偶数时:尾数直接等于原数时,此时就判断为回文数。
于是就有以下解:
int revNum=0;
while(revNum<x){
revNum=revNum*10+x%10;
x=x/10;
}
if(revNum==x||revNum/10==x)
return true;
else
return false;
二、两数和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
分析:
最简单的解法自然是使用两个循环强行求解,但是时间复杂度太高。我想了半天其实自己想不出最优解,还是参考别人的解法:
(HashMap)
首先我们可以利用 a+b=target=>b=target-a 的变换,让我们在一个循环中求有没有一个b的值等于target-a。然后这里使用到的就是HashMap.contiansKey()方法判断,如果为true则结束循环返回相对应的value。
Map<Integer,Integer> hashMap=new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;++i){
if(hashMap.containsKey(nums[target-i])){
return new int[]{nums[target - i], i};
}
hashMap.put(nums[i],i);
}
return new int[0];
三、无重复字符的最长字串
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
题目看起来很简单,但是苦思冥想了许久还是解决不了。
首先我自己的思路是:
先将字符串转换为字符数组,然后利用循环获取从第一个字符到第一个重复字符的数组下标,之后
通过两个标志量的变换,得到最长的未重复字符串。
虽然还勉强能解决几百种情况,但还是没能得到最优解。
参考解法:
(滑动窗口)
这其实是上课时老师讲过的方法,通过两个指针表示一个字符串中,为出现重复字符的字串的开始和结束,把当前的字串字符存到一个HashSet中,当最开始的为重复子串的两个指针整体向后移动时,通过HashSet的contains方法判断是否有重复字符出现。如果未重复则一直循环,如果出现重复,则与前面的未重复子串的长度进行比较,如果大于之前的则赋予新的值,如果没有大于它的则返回前面的值。
//滑动窗口
HashSet<Character> mySet = new HashSet<Character>();
int n=s.length();
int rk=-1,ans=0;
for (int i=0;i<n;++i){
if(i!=0){
//左指针右移,移除一个字符(开始滑动)
mySet.remove(s.charAt(i-1));
}
//判断右指针所在字符是否重复,不断右移,同时控制右指针不能超过字符串长度
while(mySet.contains(s.charAt(rk+1))&&rk+1<n){
//满足不重复条件时,将右指针字符添加到set中
mySet.add(s.charAt(rk+1));
//继续右移
++rk;
}
//如果出现重复的字符,则判断之前未重复的字符串长度是否未最大长度
ans = Math.max(ans,rk+1-i);
}
//返回结果
return ans;
总结:
总的来说算是个力扣小白,一点点积累吧!
重点在于坚持和对解题思想的理解。