文章目录
前言
记录跟着“代码随想录”刷力扣的过程
链接: 代码随想录
数组部分(一)
三、移除元素
844.比较含退格的字符串
使用双指针法
注意点:当退格‘#’数量大于字母数量时,要注意控制 j 的边界
class Solution {
public boolean backspaceCompare(String s, String t) {
s=get(s);
t=get(t);
if(s.equals(t)) return true;
else return false;
}
public String get(String s){
int i=0,j=0;
char[] nums=s.toCharArray();
for(i=0;i<nums.length;i++){
if(nums[i]!='#'){
nums[j++]=nums[i];
}
else {
if(j>0) j--;
}
}
s=String.valueOf(nums,0,j);
return s;
}
}
977.有序数组的平方
使用双指针法
思路:因为数组按照非递减顺序排序,所以在任意情况下元素平方的最大值在数组的最左或最右。所以用左右两个指针,分别从数组的头尾开始,依次取出较大值。
class Solution {
public int[] sortedSquares(int[] nums) {
int left=0,right=nums.length-1,index=nums.length-1;
int[] result = new int[nums.length];
while(left<=right){
if(Math.abs(nums[left]) < Math.abs(nums[right])){
result[index--]=nums[right]*nums[right];
right--;
}else {
result[index--]=nums[left]*nums[left];
left++;
}
}
return result;
}
}
四、有序数组的平方
即上述977.有序数组的平方(不知道为啥重复了)
五、长度最小的子数组
209.长度最小的子数组
解法一:暴力解。i从0开始,每个循环往后移一位,直到数组末尾。每个循环中,j从i开始,记录从i开始使sum>=target需要的长度,并与之前的长度比较获取最小长度。
解法二:滑动窗口:右边界j一直右移,sum>=target后收缩左边界 i
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i=0,j,sum=0,min=Integer.MAX_VALUE;
for(j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=target){
min=min>(j-i+1)?(j-i+1):min;
sum-=nums[i];
i++;
}
}
return min==Integer.MAX_VALUE?0:min;
}
}
904.水果成篮
滑动窗口
题目意思解释成:最多包含2个不同数字的最大窗口长度
思路:用一个Map记录数字值及其出现的次数,当记录到出现三个不同的数字时,收缩左边界,直至某一个数字在窗口中的出现次数减为0。记录此时的窗口大小。
class Solution {
public int totalFruit(int[] fruits) {
int left=0,right=0,num=0;
HashMap<Integer, Integer> map = new HashMap<>();
int i,j;
for(right=0;right<fruits.length;right++){
j=fruits[right];
map.put(j,map.getOrDefault(j,0)+1);
//收缩左边界
while(map.size()>2){
i=fruits[left];
map.put(i,map.getOrDefault(i,0)-1);
if(map.get(i)==0) map.remove(i);
left++;
}
num=num>(right-left+1)?num:(right-left+1);
}
return num;
}
}
76.最小覆盖子串
滑动窗口
注意点:
1、需要记录t中每个字母出现的次数
2、收缩左边界时,除了要剔除不属于t的字母,还要剔除冗余的字母,否则得不到最小子串
class Solution {
public String minWindow(String s, String t) {
if(s.equals("")||t.equals("")) return "";
int l=0,r;// l为窗口左边界,r为窗口右边界
String res=""; //目标子串
char[] str= s.toCharArray(); //这一步可以省略
//用一个HashMap记录t中各个字母及出现的次数
//表示还需要匹配哪些字母及他们的个数
HashMap<Character, Integer> map = new HashMap<>();
for(int i=0;i<t.length();i++) {
map.put(t.charAt(i),map.getOrDefault(t.charAt(i),0)+1);
}
int len=Integer.MAX_VALUE,match=0;//match为已匹配的个数
for(r=0;r<s.length();r++){//右边界右移
if(map.containsKey(str[r])) {
map.put(str[r],map.get(str[r])-1);
if(map.get(str[r])>=0) match++;
//如果str[r])<0 表示该字母冗余
}
//收缩左边界:当l指向的字母不属于t 或 冗余时,l++
while(l<=r&&(!map.containsKey(str[l])||map.get(str[l])<0)) {
//将冗余字母从窗口中剔除
if(map.containsKey(str[l])) map.put(str[l],map.get(str[l])+1);
l++;
}
if(match==t.length()&&(r-l+1)<len){//完全匹配
len=r-l+1;
res=s.substring(l,r+1);
}
}
return res;
}
}