lc数组题

163 阅读1分钟

总结

1.题目包含有序,元素唯一。一般都是用二分法查找法。找到对应元素返回

关键代码

注意:以后写此类代码一律left,right一律指向对应数组的值。不要直接=数组长度,后面还得减1.

int left = 0;
int right = nums.length - 1; 
while(left <= right)
mid = (left + right) / 2 
or
int middle = left + ((right - left) / 2);
  • 暴力解法时间复杂度:O(n)
  • 二分法时间复杂度:O(logn)

2.如果不使用二分的题目,一般有双循环的,都是使用双指针法。减去一个循环。减少时间复杂度。

2.1 不需要新开一个数组接收的情况下。空间复杂度1(此类题目一般都是涉及移除数组元素)

因为java数组是不变的,所以想移除数组,只能通过覆盖的方式,或者新开个数组,把需要的元素放进去。但是题目一般限制空间复杂度为1.所以别想新开数组了,乖乖双指针赋值吧

右指针指向的元素全是需要的元素(遇到不需要的--),左指针无差别指向。这样当左指针遇到不需要的,只要把右指针指向的。

通过指针的赋值达到目的

  num[left] = num[right]。right--

就行了。成功取出不需要的元素

循环条件

int left = 0;
int right = nums.length - 1;

while(left <= right)

2.2需要额外数组的情况下

一般都是左右比较,达到条件的 -- ++ 。然后把值放到另外一个数组

int[] result = new int[nums.length];
 while (left <= right) {
            if (XXXX) {
                // 正数的相对位置是不变的, 需要调整的是负数平方后的相对位置
                result[index--] = nums[left] * nums[left];
                ++left;
            } else {
                result[index--] = nums[right] * nums[right];
                --right;
            }
        }

需要用那种双指针只要看题目,规定了空间复杂度没。

双指针时间复杂度都是n。暴力都是n^2

3.滑动窗口

实际上就是双指针,但是他的双指针是朝一个方向的,一个快一个慢,移动起来像个窗口在滑动,窗口里面的值就是我们需要的值。

一般题目中要求返回 连续数组的都是用这个

因为相向的双指针,左边一下,右边一下。不可能能返回一个连续的数组给你。

一般都是右指针更快,快到需要的值满足条件,就停止。然后left指针开始往前走,找到极值后。记录下数据,在重复上面的过程知道找到最小或者最大的值。返回

for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= s) {
                result = Math.min(result, right - left + 1);
                sum -= nums[left++]; //这里是关键。左指针的移动。获取做合适的窗口数据
            }
        }

虽然用到了两个循环,但是你会发现他的操作数就是2n。所以时间复杂度为n