4.27 盛最多水的容器 && 三数之和(都是双指针)

盛最多水的容器

原理:ij指针从两边各自滑动,滑动的条件是解题的关键,解决时间复杂度较高的问题

public int solution(int[] height) {
//		int ans=0, x=0;
//		for(int i=0; i<height.length-1; i++) {
//			for(int j=i+1; j<height.length; j++) {
//				x = (j-i)*Math.min(height[i], height[j]);
//				ans = x>ans?x:ans;
//			}
//		}//暴力求解时间复杂度高
		//自己的思想陷入到ij指针只能从一编开始动,有时候应该转换一下思想,ij指针分别从头尾开始动,就可能得到时间复杂度较小的较优解
		int ans=0, i=0, j=height.length-1, x=0;
		while(i<j) {
			x = (j-i)*Math.min(height[i], height[j]);
			ans = x>ans?x:ans;
			//每次移动height较小的指针,因为木桶效应
			//面积取决于指针的距离与值小的值乘积,如果值大的值向内移动,距离一定减小,面积也一定减小,是没有意义的
			if(height[i]<height[j])i++; 
			else j--;
		}
		return ans;		
	}

三数之和

原理思想:先固定一个数值,然后再利用剪枝的思想去找剩下两个和固定数值和为0的两个数,利用ij双指针不断逼近,直至i>=j。其中的去重思想很重要,是解题的关键步骤,也是降低时间复杂度的一种方法(避免重复的查找)。

public List<List<Integer>> solution(int[] nums) {
		Arrays.sort(nums);//排序
		int k=0, i=1, j=nums.length-1;
		List<List<Integer>> result=new LinkedList<>();
		for( ; k<nums.length-2; k++) {//为什么是-2,因为ij需要占据一个位置,到最后一次循环k=length-3, i=length-2, j=length-1
			//最小的都大于0,没有找的意义了
			if(nums[k]>0)break;
			//固定的数num[k]和num[k-1]相同,代表num[k-1]的结果已经找过了,用k去重,跳出这次循环
			if(k>0 && nums[k] == nums[k-1])continue;
			//每次k循环结束都要重新对ij赋值
			i=k+1;
			j=nums.length-1;
			//结束条件,ij指针指向同一数值
			while(i<j) {
				//sum和小于0,就将i指针向右移动,增加sum
				if(nums[k]+nums[i]+nums[j]<0) {
					i++;
				}
				else if (nums[k]+nums[i]+nums[j]>0) {
					j--;
				}
				else {
					List<Integer> res=new LinkedList<>();
					res.add(nums[k]);
					res.add(nums[i]);
					res.add(nums[j]);
					result.add(res);
					//用ij去重,和为0后就要缩小指针范围:i++,j--
					//但是可能出现nums[]中的数值相等的情况,这个结果已经考虑过了,为什么?
					//因为在一次循环中,nums[k],nums[i]是确定的,如果下次i++,得到的nums[i+1]==nums[i],那么再次找到的nums[j]的值一定是重复的
					while(i<j && nums[i]==nums[i+1])i++;
					while(i<j && nums[j]==nums[j-1])j--;
					i++;j--;
				}
			}
		}
		return result;
	}

LinkedList和ArrayList的区别

ArrayList 和 LinkedList 是 List 接口的两种不同实现。ArrayList 内部使用的动态数组来存储元素,LinkedList 内部使用的双向链表来存储元素,这也是 ArrayList 和 LinkedList 最本质的区别。

需要注意的是,如果列表很大很大,ArrayList 和 LinkedList 在内存的使用上也有所不同。LinkedList 的每个元素都有更多开销,因为要存储上一个和下一个元素的地址。ArrayList 没有这样的开销,其更加轻量级。

但是,ArrayList 占用的内存在声明的时候就已经确定了(默认大小为 10),不管实际上是否添加了元素,因为复杂对象的数组会通过 null 来填充。LinkedList 在声明的时候不需要指定大小,元素增加或者删除时大小随之改变。

另外,ArrayList 只能用作列表;LinkedList 可以用作列表或者队列,因为它还实现了 Deque接口


还要注意new一个list对象要用linkedlist或者arraylist,因为list是接口

List<Integer> aIntegers=new LinkedList<>();
List<Integer> aIntegers=new ArrayList<>()

快速打印list元素

		List<String> list = new ArrayList<String>();
		list.add("a");
		list.add("b");
		list.add("c");
		System.out.println(Arrays.toString(list.toArray()));


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值