977.有序数组的平方
class Solution {
public int[] sortedSquares(int[] nums) {
//分为暴力破解法和双指针法:双指针法思路:创建一个新的数组,旧数组的平方要么在两端,不可能在中间,所以用i指向旧数组头,j指向新数组的尾部
int i = 0;
int j = nums.length-1;
int index = j;
int[] newarry = new int[j+1];
while(i <= j){
if (nums[i] * nums[i] < nums[j] * nums[j]){
newarry[index] = nums[j] * nums[j];
j--;
}
else{
newarry[index] = nums[i] * nums[i];
i++;
}
index--;
}
return newarry;
}
}
209.长度最小的子数组
//暴力算法 不推荐 O(n^2)
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int result = INT32_MAX; // 最终的结果
int sum = 0; // 子序列的数值之和
int subLength = 0; // 子序列的长度
for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
sum = 0;
for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
sum += nums[j];
if (sum >= s) { // 一旦发现子序列和超过了s,更新result
subLength = j - i + 1; // 取子序列的长度
result = result < subLength ? result : subLength;
break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
}
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
在本题中实现滑动窗口,主要确定如下三点:
- 窗口内是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
//滑动窗口算法
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//使用滑动窗口解法
int sum = 0;//滑动窗口内部的数组和
int i = 0;//滑动窗口起始位置
int j = 0;//滑动窗口结束位置
//通过先确定滑动窗口的结束位置,再不断改变滑动窗口的起始位置
int result = Integer.MAX_VALUE;
int sublenth = 0;//滑动窗口的宽度
for(j = 0; j < nums.length; j++){
sum += nums[j];
while( sum >= target){
sublenth = j - i + 1;
result = result < sublenth ? result : sublenth;
sum -= nums[i++];
}
}
return result == Integer.MAX_VALUE ? 0 :result;
}
}
904. 水果成篮
904. 水果成篮
本题使用了Java中的hashmap和滑动窗口的结合,注意hashmap中的get(),put(),getOrDefault() 等方法
class Solution {
public int totalFruit(int[] fruits) {
//hashmap + 滑动窗口 hashmap中存储的键值对是(窗口内)果树的种类-果树的棵树
int left = 0;
int right = 0;
int ans = 0;
Map<Integer,Integer> cnt = new HashMap<Integer,Integer>();
for (right = 0; right < fruits.length; right++){
cnt.put(fruits[right],cnt.getOrDefault(fruits[right],0) + 1);
while(cnt.size() > 2){
//如果说hashmap中存储了2个以上的键值对,则从Left开始缩小滑动窗口
//首先将hashmap中以fruits[left]为键的值减1
cnt.put(fruits[left],cnt.getOrDefault(fruits[left],0)-1);
if(cnt.get(fruits[left])==0){
//如果hashmap中以fruits[left]为键的键值的个数为0,则删除该键值对
cnt.remove(fruits[left]);
}
left++;
}
ans = Math.max(ans, right - left + 1);
}
return ans;
}
}
76. 最小覆盖子串
76. 最小覆盖子串
难度较高
class Solution {
Map<Character,Integer> ori = new HashMap<Character,Integer>();
Map<Character,Integer> cnt = new HashMap<Character,Integer>();
public String minWindow(String s, String t) {
//使用滑动窗口算法,首先将t目标字符串映射到ori中,键值对
int tLen = t.length();
for ( int i = 0; i < tLen; i++){
char c = t.charAt(i);
ori.put(c,ori.getOrDefault(c,0)+1);
}
int l = 0 ,r = -1;
int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
int sLen = s.length();
while(r < sLen){
++r;
if(r < sLen && ori.containsKey(s.charAt(r))){
cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r),0)+1);
}
while(check() && l <= r){
if(r - l + 1 < len){
len = r - l + 1;
ansL = l;
ansR = l + len;
}
if(ori.containsKey(s.charAt(l))){
cnt.put(s.charAt(l),cnt.getOrDefault(s.charAt(l),0) -1);
}
l++;
}
}
return ansL == -1 ? "" :s.substring(ansL,ansR);
}
//check()函数的原理还不是很清楚
public boolean check() {
Iterator iter = ori.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Character key = (Character) entry.getKey();
Integer val = (Integer) entry.getValue();
if (cnt.getOrDefault(key, 0) < val) {
return false;
}
}
return true;
}
}
59.螺旋矩阵II
59.螺旋矩阵II
使用模拟的方法生成螺旋矩阵:left to right, top to bottom, right to left ,bottom to top
class Solution {
public int[][] generateMatrix(int n) {
int l = 0, r = n - 1, t = 0, b = n - 1;
int[][] mat = new int[n][n];
int num = 1, tar = n * n;
while(num <= tar){
for(int i = l; i <= r; i++) mat[t][i] = num++; // left to right.
t++;
for(int i = t; i <= b; i++) mat[i][r] = num++; // top to bottom.
r--;
for(int i = r; i >= l; i--) mat[b][i] = num++; // right to left.
b--;
for(int i = b; i >= t; i--) mat[i][l] = num++; // bottom to top.
l++;
}
return mat;
}
}