LeetCode做题笔记
Add two numbers:给定一个数集合和一个数,已知集合中有两个数的和是给定数,求这两个加数的index
方法1:暴力,n^2时间复杂度,不推荐
方法2:快速排序nlogn。按集合里数的两倍与target的大小关系对分。对每一个第一部分的数,在另外一个部分二分搜索第二个数:500~ms
方法3:hash,n的时间复杂度,最高纪录420ms
方法3源码:
public int[] twoSum(int[] numbers, int target) { //index Map Map<Integer, Short> indexMap = new HashMap<>(); int x; //hash value and indices for (short i = 0; i < numbers.length; i++){ x = numbers[i]; if (indexMap.get(x) == null) indexMap.put(x, i); else { if (target == x * 2){ return new int[] {indexMap.get(x) + 1, i + 1}; } } } for (short i = 0; i < numbers.length; i++){ x = numbers[i]; if (target != x * 2 && indexMap.get(target - x) != null){ int int1 = indexMap.get(x) + 1; int int2 = indexMap.get(target - x) + 1; if (int1 > int2) return new int[] {int2, int1}; else { return new int[] {int1, int2}; } } } return null; }
经验1:对hashMap的get和put都是非常耗时间的,尽量少做
经验2:方法2最好使用随机化快排,效率很高
把两个链表表示的数加起来:最佳624ms,3%
用长一点的链表做基础,最多只需要new一个新节点
优化建议:进位尽量用数字。如果一个链到头了,另一个没到,应该沿着长链前进。如果进位是0就可以即刻返回,不需要继续前进。
源码:
public class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { int sum, progress = 0; ListNode tmp1 = l1, tmp2 = l2; for (;;){ sum = l1.val + l2.val +progress; progress = sum >= 10 ?1 : 0; l1.val = l2.val = sum>= 10 ? sum - 10 : sum; if (l1.next == null){ if (l2.next == null){ if (progress ==1) l2.next= new ListNode(1); return tmp2; } else { l2 =l2.next; } for (; ;){ if (progress ==0) returntmp2; ++l2.val; progress =l2.val >= 10 ? 1 : 0; l2.val = l2.val>= 10 ? 0 : l2.val; if(l2.next == null){ if(progress == 1) l2.next= new ListNode(1); break; } else l2 =l2.next; } return tmp2; } if(l2.next == null){ l1 = l1.next; for (; ;){ if(progress == 0) returntmp1; ++l1.val; progress =l1.val >= 10 ? 1 : 0; l1.val = l1.val>= 10 ? 0 : l1.val; if(l1.next == null){ if(progress == 1) l1.next= new ListNode(1); break; } else l1 =l1.next; } return tmp1; } l1 = l1.next; l2 = l2.next; } } }
经验2:leetcode不靠谱啊,速度不一定对
把一个整数数位逆转,注意符号,不能溢出
最好记录404ms,前5%
public static int reverse(int x) { StringBuilder string = new StringBuilder(x + ""); int flag = 1; if (string.charAt(0) == ‘-‘){ flag = -1; string.reverse().deleteCharAt(string.length()-1); } else { string.reverse(); } try{ return flag == 1 ? Integer.parseInt(string.toString()) : -1 *Integer.parseInt(string.toString()); } catch (Exception e){ return 0; } }
经验3:类库比较快。而且好像早上/翻墙以后机器运算比较快?
官方提示:
To check for overflow/underflow, we could checkif ret > 214748364 or ret < –214748364 before multiplying by 10. On theother hand, we do not need to check if ret == 214748364, why? 溢出是2147483647,214748364乘10不溢出
原文地址:http://08310302.blog.51cto.com/7006444/1597994