刷题网站 :https://leetcode-cn.com/
github地址 : https://github.com/zhe8300975/myleetcode
文章目录
整体总结
简单难度 1、7、9
中等难度 187
本次刷题 总结 以下3个“又”
- 又出现了 ascii码 char加减法
- 又出现了 借助基本数据类型 用以空间换时间
- 又出现了边界条件
本地刷题难度大体和第一次刷题难度一样 但是针对长期不刷题的你我 很有助于找会感觉 而且不会被打击 可以保持兴趣,两次刷题总结出的经验比较重要 一定铭记于心,尤其是边界条件。
其实刷题和高考做题一样,在应试教育的背景下,大家都知道怎么解,最后拼的还是细节。
LeetCode 1
题目 —— 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
思路
在没有任何前提的情况下 俩个数之和第一反应一个双重for循环解决问题 O(n)解决,但是做人做事还是要有点追求。怎样能O(n)下解决呢
其实当我们遍历的一个值之后我们就知道能凑成目标的值是多少 那问题就简化成我通过一个值怎么能找到这个值的位置 利用map很容易可以解决这个问题
解题
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<nums.length;i++){
if(map.containKey(target - nums[i])){
return new int[]{map.containKey(target - nums[i]), i};
}else{
map.put(nums[i],i);
}
}
}
LeetCode 7
题目 —— 整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
输入: 123
输出: 321
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
思路
乍一看以为送分题 很符合人类逻辑 一个循环,取输入端与10的余数 输出端乘以10加余数 然后快速coding
public int reverse(int x) {
int result=0;
while(x!=0){
result*=10;
result=result+x%10;
x/=10;
}
return result;
}
然后咔嚓 不过 纳尼 溢出了怎么办?重新身审题 原题下面一行小字 提醒了这个问题,不仅悔恨 那怎么解决呢 那就是在计算前判定下了 因为正负值边界不一样所以需要分开判断
解题
public int reverse(int x) {
int result = 0;
while (x != 0) {
if (result < 0 && (result < Integer.MIN_VALUE / 10 || (Integer.MIN_VALUE / 10 == result && x % 10 < Integer.MIN_VALUE % 10)))
return 0;
if (result > 0 && (result > Integer.MAX_VALUE / 10 || (Integer.MAX_VALUE / 10 == result && x % 10 > Integer.MAX_VALUE % 10)))
return 0;
result *= 10;
result += x % 10;
x /= 10;
}
return result;
}
LeetCode 9
题目 —— 回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
思路
刚做完7题 基础之上自然而然想想到 整数翻转,如果新值和翻转后的值相等就是回文数 因为能传入表示出来的正整数 一定小于int最大值 回文正整数倒置后等于原来的正整数 所以本地倒置不需要关心边界条件
解题
public boolean isPalindrome(int x) {
if (x < 0) {
return false;
}
int result=0;
int x1=x;
while(x1!=0){
result=result*10+x1%10;
x1/=10;
}
return result==x;
}
LeetCode187
题目 —— 重复的DNA序列
所有 DNA 都由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来查找目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。
输入:s = “AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT”
输出:[“AAAAACCCCC”, “CCCCCAAAAA”]
思路
一下子没有思路 那就先抽离有用的条件
- 子串的长度为 10
- 字符串 s 中出现次数超过一次
转化一下 - 我们需要一个我们需要一个长度为10的char数组
- 我们需要记录 char数组炸展示的次数 ——map
随即就有了一个简单思路就是
遍历一边记录 每个字串出现的次数
解题
public static List<String> findRepeatedDnaSequences(String s) {
List<String> list = new ArrayList<>();
HashMap<String, Integer> hashMap = new HashMap<>();
for (int i = 0; i < s.length() - 9; i++) {
String dna = s.substring(i, i + 10);
Integer num = hashMap.get(dna);
if (num == null) {
hashMap.put(dna, 1);
} else {
hashMap.put(dna, ++num);
}
}
for (Map.Entry<String, Integer> item : hashMap.entrySet()) {
if (item.getValue() > 1) {
list.add(item.getKey());
}
}
return list;
}
这样真的是最优解么 看了下官方答案 其实官方的的解决方案和我这个类似不过细节上有了更好的优化 其实在代码写完的时候 我们其实就发现了 最后为了输出结果会有一个循环的创建list的过程 那么官方答案的优化其实就是利用不同数据结构的特性 解决了这个问题
public List<String> findRepeatedDnaSequences(String s) {
int L=10;
HashSet<String> out = new HashSet<>();
HashSet<String> hashSet = new HashSet<>();
for(int i=0;i<s.length()-L+1;i++){
String str=s.substring(i,i+L);
if(hashSet.contains(str)){
out.add(str);
}else{
hashSet.add(str);
}
}
return new ArrayList<String>(out);
}