代码随想录Day-03|双指针、滑动窗口

88 阅读3分钟

代码随想录Day-02|移除数组元素、有序数组的平方、长度最小的子数组

移除元素

  • 方法一:暴力 两层for循环 一层来正常遍历来找是否有相等的,另一层把后面的元素往前移

注意事项:

1.第二层的变量ji+1开始

2.第一层的i要退回去i--

  • 方法二:双指针(也叫做快慢指针法)

快指针用来寻找放进去的元素,慢指针则表示新数组下标位置,通过

int slow=0;
arr[slow++]=fast;

来达到目的。时间复杂度:O(n)

特点:双指针法(快慢指针)在数组和链表的操作中非常常见

有序数组的平方

原题是 非递减顺序排序的整数数组

  • 方法一:暴力排序给每个数平方排序,时间复杂度是 O(n + nlogn)

  • 方法二:双指针 个人见解:平方看成是数学函数n*2,定义1个数组来装(最大值通过比较两边比较所得),关键代码是

for (int i = 0, j = A.size() - 1; i <= j;)
	result[k--] = A[j] * A[j];

注意事项:

1.数组下标不用专门去循环来写

2.对于取大时的不同情况分类讨论i++还是j--。这里时间复杂度为O(n)

3.还有对于判断条件时取等:i <= j,若不取当i==j时就退出了,就落了一个元素

长度最小的子数组

  • 方法一:暴力两层for循环,一个一个找,有专门的存放长度差小的数组,不用担心有漏的,i会逐步往前逼近(在一段区间内不断收集),然后再往下一个区间(以sum为条件)

类似这种感觉:是一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置

 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
                }
            }
        }
  • 方法二:滑动窗口就是先移动遍历的指针,左边的再根据sum去调整,时间复杂度:O(n)

滑动窗口(数组常见操作):就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果

那么肯定只用一个for循环,但是表示的一定是滑动窗口的终止位置

 minLength = minLength < subLength ? minLength : subLength;

一开始可以定义为最大的的去比较!

要求的滑动窗口内容如下 PixPin_2024-12-28_23-12-03.png

今日额外知识补充:java中注释时既不参与编译也不参与运行,可以用来debug

java中关键字是被java赋予特殊含义的英文单词