1、977.有序数组的平方
题目链接:977.有序数组的平方
文章讲解:代码随想录
视频讲解:代码随想录
解题思路:双指针进行求解:
a、非递减顺序的整数数组;
b、可能存在负数;
c、数组的值经平方后,最大值只可能出现在左右两侧;
d、按非递减顺序排序输出
双指针适用场景(摘自网络):
双指针算法在数组相关的算法中经常被使用,特别是在需要查找或处理满足特定条件的子数组、子字符串或两个数组之间的关系时。以下是一些适用双指针算法的常见场景:
1. 有序数组的查找:当给定的数组是有序的时候,可以使用双指针来进行查找。通过将一个指针指向数组的开头,另一个指针指向数组的末尾,根据当前指针所指元素与目标值的大小关系,逐步缩小查找范围。
2. 两数之和:给定一个有序或无序的数组,需要找到两个元素的和等于目标值的索引。通过使用两个指针,一个指向数组的开头,另一个指向数组的末尾,根据两个指针所指元素之和与目标值的大小关系,逐步缩小查找范围。
3. 反转数组或字符串:通过使用两个指针,一个指向数组或字符串的开头,另一个指向数组或字符串的末尾,交换两个指针所指元素的值,并向中间移动指针,从而实现反转。
4. 快慢指针:用于解决一些链表相关的问题,如判断链表是否有环、找到链表的中间节点等。通过使用两个指针,一个指针每次移动一个位置,另一个指针每次移动两个位置,可以在一次遍历中解决问题。
5. 归并两个有序数组:给定两个有序数组,需要将它们合并成一个有序数组。通过使用两个指针分别指向两个数组的末尾,比较两个指针所指元素的大小,并逐步将较大的元素放入合并后的数组中。
这些只是双指针算法的一些常见应用场景,实际上它们还可以用于解决其他一些数组相关的问题。双指针算法通常能够在O(n)的时间复杂度内解决问题,因此在面对大规模数据时具有高效性能。
时间复杂度:O(n)
空间复杂度:O(1)
代码片段:
class Solution {
public int[] sortedSquares(int[] nums) {
int l = 0;
int r = nums.length -1;
int[] res = new int[nums.length];
int index = nums.length - 1;
while(l <= r){
if(nums[l] * nums[l] > nums[r] * nums[r]){
res[index--] = nums[l] * nums[l++];
}else{
res[index--] = nums[r] * nums[r--];
}
}
return res;
}
}
2、209.长度最小的子数组
题目链接:209.长度最小的子数组
文章讲解:代码随想录
视频讲解:代码随想录
解题思路:滑动窗口进行求解:
a、定义两个指针start和end,分别标识子数组的开始位置和结束位置
b、第一轮迭代,end指针向右移动至子数组的和大于目标值
c、start指针逐一向右移动,直至子数组的和小于目标值,此时获取数组的长度end-start
d、不断迭代,取每一轮获取到的长度的最小值
滑动窗口适用场景(摘自网络):
滑动窗口是一种常用的算法技巧,用于解决数组或字符串相关的问题。它适用于需要在数组或字符串中寻找特定子数组或子字符串的问题,例如求解最长子串、最小覆盖子串、子数组和等。
滑动窗口算法的基本思想是维护一个窗口,通过移动窗口的起始位置和结束位置来寻找满足条件的子数组或子字符串。以下是一些适用滑动窗口算法的常见场景:
1. 最长子串或最小覆盖子串:给定一个字符串,需要找到其中包含指定字符或满足特定条件的最长子串或最小覆盖子串。通过使用两个指针,一个指向窗口的起始位置,另一个指向窗口的结束位置,根据当前窗口中的字符或条件判断,逐步扩大或缩小窗口,直到找到满足条件的子串。
2. 子数组和或子数组乘积:给定一个数组,需要找到连续子数组的和或乘积等于目标值的子数组。通过使用两个指针,一个指向窗口的起始位置,另一个指向窗口的结束位置,根据当前窗口中的元素和或乘积与目标值的大小关系,逐步扩大或缩小窗口,直到找到满足条件的子数组。
3. 字符串排列或找到所有字母异位词:给定一个字符串和一个模式串,需要找到字符串中所有满足模式串的排列或字母异位词的子串。通过使用两个指针,一个指向窗口的起始位置,另一个指向窗口的结束位置,根据当前窗口中的字符和模式串的字符频次关系,逐步扩大或缩小窗口,直到找到满足条件的子串。
滑动窗口算法通常能够在O(n)的时间复杂度内解决问题,因此在面对大规模数据时具有高效性能。然而,滑动窗口算法的实现可能需要一些技巧和条件的判断,因此在应用时需要注意细节。
时间复杂度:O(n)
空间复杂度:O(1)
代码片段:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for(int right = 0; right < nums.length; right++){
sum += nums[right];
while(sum >= target){
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 :result;
}
}
3、59.螺旋矩阵II
题目链接:59.螺旋矩阵II
文章讲解:代码随想录
视频讲解:代码随想录
解题思路:按层模拟进行求解:
a、将矩阵看成若干层,每一圈属于同一层,左开右闭可以拆分成相同长度
b、按上侧、右侧、下侧、左侧的循环形式,填充二阶数组
c、注意奇数时,最内层元素只有一个,需要条件判断,然后进行填充
时间复杂度:O(n²)
空间复杂度:O(1)
代码片段:
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0;
int[][] res = new int[n][n];
int start = 0;
int count = 1;
int i,j;
while(loop++ < n / 2){
for(j = start; j < n - loop; j++){
res[start][j] = count++;
}
for(i = start; i < n -loop; i++){
res[i][j] = count++;
}
for(; j >= loop; j--){
res[i][j] = count++;
}
for(; i >= loop; i--){
res[i][j] = count++;
}
start++;
}
if( n % 2 == 1){
res[start][start] = count;
}
return res;
}
}