2018 11 17ARTS(5)

what?什么是ARTS

  • Algorithm:每周至少做一个leetcode的算法题;
  • Review:阅读并点评至少一篇英文技术文章;
  • Tip/Techni:学习至少一个技术技巧;
  • Share:分享一篇有观点和思考的技术文章;

Algorithm:每周至少做一个leetcode的算法题

本周的题目:

三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出> 所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]

满足要求的三元组集合为: [[-1, 0, 1], [-1, -1, 2]]

具体连接:https://leetcode-cn.com/problems/3sum/description/

这个题目真的有点难,从昨天晚上做到今天早上,不断的调优,查了一些资料才解决。这个题目是从另一道题目两数之和知道的。

但是难度显然不是一个级别的,这道题目对答案的时间的要求好像挺严格的,很容易就超出时间限制了,这种要求导致我每次提交代码都是心惊肉跳的,希望答案可以通过。 刚刚开始第一反应就是暴力遍历了,就是使用三次循环。具体代码,额,这里就不贴了,就是要注意的是,题目中有信息很关键,要无重复的结果,也就是说

[-1,0,1], [0,-1,1], [1,-1,0] 这三个答案只能算一种个,结果中只能出现其中一个。

所以需要增加一个去重的操作,这个有点略坑,还搜寻了一翻。 就是在结果中加上一个给list的排序,然后判断是否存在。

Comparator<Integer> threeComparable = new Comparator<Integer>() {
	@Override
	public int compare(Integer o1, Integer o2) {
		return o2 - o1;
	}
};
List<List<Integer>> result = new LinkedList<>();
List<Integer> tempList = Arrays.asList(nums[i], nums[j], nums[k]);
// 排序
tempList.sort(threeComparable);
// 判断重复
if (!result.contains(tempList)) {
	result.add(tempList);
}

以上就是原来为了去重写的代码。当然在后来的代码不断优化当中,这个代码就用不上了。但是感觉还是有点用,这里还是贴一下。顺便这里贴一下这个算法的图解。

所以就想到了要使用双指针,但是双指针的移动需要有个判断条件的,也就说,你需要有个条件来判断什么时候移动左边的指针,你什么时候移动右边的指针,根据判断的条件来减少循环的次数,不然说到底还是三次循环。因为需要判断的条件,因为数组中都是数字,首先想到的是根据大小来作为判断的根据,因为要根据大小,我们需要先把整个数组进行一次排序,用Java的数组函数进行一次排序。然后就取i之后的一个坐标作为左(数字小)指针,最后一个坐标作为右(数字大)指针,然后根据和结果比大小的方式来判断是移动左边的指针还是右边的指针。

public List<List<Integer>> threeSum(int[] nums) {
	Arrays.sort(nums);
	List<List<Integer>> result = new LinkedList<>();
	int length = nums.length;
	for (int i = 0; i < length - 2; i++) {
		// 去重判断
		if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) {
			int lowIndex = i + 1;
			int highIndex = length-1;
			while (lowIndex < highIndex) {
				int targetC = 0 - nums[i] - nums[lowIndex];
				if (targetC == nums[highIndex]) {
					List<Integer> tempList = new ArrayList<>();
					tempList.add(nums[i]);
					tempList.add(nums[lowIndex]);
					tempList.add(nums[highIndex]);
					result.add(tempList);
					// 去重判断
					while (lowIndex < highIndex && nums[lowIndex] == nums[lowIndex + 1]) {
						lowIndex++;
					}
					// 去重判断
					while (lowIndex < highIndex && nums[highIndex] == nums[highIndex - 1]) {
						highIndex--;
					}
					highIndex--;
					lowIndex++;
				} else if (targetC > nums[highIndex]) {
					lowIndex++;
				} else {
					highIndex--;
				}
			}
		}
	}
	return result;
}

这里的代码说一下,因为需要去重,这里的数组是通过排序的,那么就会出现相同的数字排在相邻的情况。如果出现这样的情况,就需要跳过这样情况,中间的两个while判断,就是实现这种功能,同样的,for下面的第一个if也是这样的功能,相同的数字我们只需要一个判断就够了,其他只要跳过就行。这些代码的图解大概这样,当然指针到底是左移还是右移,是要看条件判断的。

大概就是这样了,两个指针分别移动,这样可以吧时间复杂度降到O(n^2)。代码提交,可以通过。

Review:阅读并点评至少一篇英文技术文章;

Creating Your First Blockchain with Java. Part 1.

感觉Medium上面技术文章真的很多啊,这篇文章说的就是用Java来写区块链,说真的,我以前感觉知道啥是区块链,但是又说不清楚,这东西对我来说真的抽象,但是看到了代码实现我就感觉我有点晓得它是什么了,第一反应是感觉像链表?这边文章有配图,有代码,非常适合入门学习,完全可以自己上手写一遍的,区块链技术就算现在用不到,了解一下也是很好的,因为学技术感觉就是这样的,很多学了的东西你说不定什么时候就用上了。

Tip/Techni:学习至少一个技术技巧

本周看的比较多的《图解TCP/IP》,复习了一些和IP地址相关的信息。不然IP的那些知识就有些废了。

Share:分享一篇有观点和思考的技术文章

Why is a Java guy so excited about Node.js and JavaScript?

这篇文章讲了一个Java Guy(其实就是作者自己)如何爱上JavaScript的,说了后者的一写优点,说了Java的一些缺点,并且对二者的一些工具进行比较,Java的Maven和JavaScript的NPM,我自己对JavaScript只能说会写会用,但是说不上精通,作者说的很多优点我感觉没体会到啊。倒是下面的评论者的一些我倒是体会到了,Promise的功能待完善之类的,反正我到现在依然觉得Java好啊,怎么说呢,清晰啊,说句丢人的,我到现在看好多JavaScript的代码还会看不懂,总是感觉好灵活啊,可能没学到家吧。。。

转载于:https://my.oschina.net/jamesfuxk/blog/2877566

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值