leetcode hot100 4-7 思路

8/12

4 移动0(将所有非零元素移动到前面,0元素移动到后面,且顺序不改变)

思路:

1 双指针遍历,指针1之前表示以整理好的数组,指针2指向待排序数字,如果指针2为非0元素,则和指针1的元素交换

2 按顺序记录所有非0元素的值,后面全部赋值为0,双指针,指针1指向已排序好的非0元素,指针2指向未排序的非0数组,指针2指向非0元素,则复制给指针1的元素交换。

5 乘最多水的容器(坐标轴y作为壁,问如何与x轴一起装下最多的水)

思路:

1 遍历穷举o(n^2)超时。如何剪枝减少时间复杂度。面积=长*宽,数组元素个数确定,我们可以想到将长(即x)拉到最大,之后向着两端减少改变高(哪边的高小,哪边缩进),进行一次遍历得到最大值

核心代码:

导入Math包,用到Math.min()

6 三数之和(在数组中选出三个数,若这三个数的和等于0,则将这三个数组成的数组加入Arraylist中,且不能包括重复的三元组)

思路:

三个数之和=0,直接想到穷举o(n^3),要不重复,因此可以先给数组进行排序,在旁段(1,2,3)这三个位置的数字是否和之前一样,一样则直接跳到下一个元素,保证不重复。但是o(n^3)时间复杂度太大。如何进行优化,如果我们已经穷举了两个数,那么只有唯一的c,使得a+b+c=0,因此从最大的地方开始穷举c,并保证其下标不小于b,且c的位置得以保存,是的这两轮穷举并到一轮。

核心代码:

List<List<Integer>> ans = new ArrayList<>();

List<Integer> list = new ArrayList<Integer>();

int target = -nums[i];

int k = n-1;

for(int j=i+1; j<n-1; j++){

if(j>i+1 && nums[j]==nums[j-1]){

continue;

}

while(j<k && nums[j] +nums[k] > target){

--k;

}

if(j == k){

break;

}

if(nums[j] + nums[k] == target){

List<Integer> list = new ArrayList<Integer>();

list.add(nums[i]);

list.add(nums[j]);

list.add(nums[k]);

ans.add(list);

}

}

7 接雨水,数组之为实心柱子的高度,问数组这些柱子能接住多少雨水

思路:

这边是问一共能接住多少雨水。因此可以一个位置一个位置的算这边能接住多少雨水,加起来就是一共能接住多少雨水,发现,一个位置接住的雨水数=min(这个位置柱子左边的最高位置, 这个柱子右边的最高值)-这个柱子的高度。这样其空间复杂度为o(n)在算法中是可以接受的。

但是如何降低空间复杂度。我们使用动态规划的方法计算其左边的最大值和右边的最大值,left[i] = max(height[i],left[i-1]),因此这边可以维护leftmax和rightmax两个数来零时存储左边的最大值和右边的最大值。并初始化两个指针left和right。

当leftmax<rightmax 位置left的rightmax不确实,但是其leftmax是确定的,且比rightmax来的小,因此其面积就为leftmax-height[left],++left。

反之类似。

核心代码:

import java.lang.Math;

for(int i=1; i<n; i++){

            left[i] = Math.max(left[i-1], height[i-1]);

        }

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值