[Java coding] leetcode notes

时间:2023-01-21 18:48:24

1, 如何不排序而找到最大,次大或者最小值?

var int max1, max2, min1;

iterate array once: update max1, max2, min1, for example: if(A[i]>max1){max2=max1; max1=A[i];}...

2, 关于括号对称性的问题,如果String包含多种括号类型,需要用Stack。如果String只包含一种括号类型,例如"()",那么只需一个var int leftBrackets来存储'('的数量即可,遇到')'减1,遇到'('加1。

3, Leader问题:

int size = 0; int leader = -1; for(int i = 0; i< A.length; i++) { if(size==0) { leader = A[i]; size++; } if(A[i]==leader) size++; else size--; } if(size==0) return -1; int pos=-1; int count = 0; for(int i=0; i<A.length; i++){ if(A[i]==leader) count++; pos = i; } if(count > A.length/2) return pos; return -1;

Dominator有个进阶题Equi-leader,大意是将数组一分为二,左右的Leader相同,求这样的分割点个数。乍一看以为要做多次Dominator的计算,有一点非常重要:

如果一个数在左右子数组中都是Leader,那么它必然也是原数组的Leader

因此我们只需找出原数组的Leader并记录Leader出现的次数c,然后再枚举分割点,求Leader在左子数组出现的次数n,再看n和c-n是否都能hold住各自的那一半数组就OK啦。

4, Max Slice问题

Given an array A consisting of N integers, returns the maximum sum of any slice of A. The sum of a slice (P, Q) is the total of A[P] + A[P+1] + ... + A[Q]. 原理就是用个变量update来不断地加数,但如果加出来为负数,那下次加之前就归0,抛弃它因为负数没有效果。

public int solution(int[] A) {
// write your code in Java SE 8
int update = A[0];
int result = A[0];
for(int i=1; i<A.length; i++){
if(update < 0) update = 0;
update += A[i];
result = Math.max(result, update);
}
return result;
}

Start from Difficulty 1:

1, Remove specified elem from unsorted array: 2 pointers, one is to iterate all the elements in the array, the other is to increase if current value is not equal to specified element.

2, Remove duplicates from sorted array: still 2 pointers, compare current value with previous.

3, Remove 3rd duplicate from sorted array: on 2, have another var to store the appearance number.

4, Remove duplites from sorted linked list: prev & curr, then pay attention to null head input.

5, Length of last word: "A cat " should return 3. From end of string, find the first occurance of non ‘ ’; then from this position, calculate the non ' ' count, until ' ' appears.

6, plus 1: example {3, 9, 9} +1 = {4, 0, 0}, {9, 9, 9} + 1 = {1, 0, 0,0}. 从数组末位开始往前iterate,如果为9,则变为0,否则的话加1后直接return。最后forloop之外,表明最高为也进位了,create一个长度加1的数组,只设定第一位为1即可,其余默认为0。这样不用carry var即可。

7, same tree: recursion, return true if both are null, return false if one is null one is non-null, return current value equality && left node equality && right node equality.

8, symmetric tree: recursion, similar with same tree, trick is calling the function ifSymmetric(left.left, right.right) && ifSymmetric(left.right, right.left); 因为对称性,所以左结点的左和右结点的右比较,左结点的右和右结点的左比较。

9, maximum depth of binary tree: recursion.

10, balance binary tree: similar with maximum depth, and also if Math.abs(leftDepth, rightDepth) >1, return -1.

11, Minimum depth of binary tree: similar with max depth, difference is to judge it child is null, if yes, should return the depth of non-null child +1.

12, Path sum: my solution is recursion, not bfs, every time pass the sum-node.val, return if current node is leaf node and value equals to the passed-in sum.

13, Word ladder II: still BFS, pending.

Continue with Difficulty 2:

14, Two sum: 用hashmap复杂度O(n),或者先排序数组,用两个指针分别从头和尾向中间走,寻找和为target的index,复杂度为O(nlogn)。类似于3sum, 就是对于i=0, j=i+1, k=length-1, 头尾指针是j和k,向中间走,找到和为-arr[i]的,复杂度为O(n^2)。

15, Reverse Integer: 如果转成char array来反转麻烦的是要handle前面为0的部分,100->001。好的方法是直接用取余的方式,321%10=1, ret=0*10+1; 32%10=2, ret=1*10+2=12; 3%10=3, ret=12*10+3=123;

Java中int的范围是-2^31~ 2^31-1,因为最高位是符号位,例如8位的最高正数是0111 1111=2^7 -1=127,最低负数是1000 0000=-128,负数(补码)是正数原码的反码+1,不管多少位-1总是表示为1111 1111。

16, Merge two sorted list: 可以把新List的head设为一个dummy head= new ListNode(-1),这样就省去了在循环里判断head是否为空,而且当其中一个list循到尾后,这个判断要放在while loop之外,否则你还得把非空的这个list也循到尾才能退出while loop的condition。

17, Count and Say:Just check if curr char == prev char, if yes, count++, if not, sb.append(count).append(prev.charAt(i-1)).

18, isValidSudoku: use helper boolean array, for example, cols[j][c], if cols[j][5]==true, means 5 already appears once in column j.

19, Merge two sorted array: 将数组A覆写. different from two deck of pokers, this can be done from bottom of two arrays, k=m+n-1, A[k--]=A[i--](ifA[i]>B[j]) or B[j--].

20, Valid Palindrome: 判断String是否是对称的,只考虑a-z 0-9,特别的是可以将原String用replaceAll(String regex, String replace)来去除掉特别字符,例如String test2 = test.replaceAll("[^a-zA-Z0-9]", ""); 或是test.replaceAll("\\W", "");

21, Add Binary: still two pointers, just fyi: char to int: Character.getNumericValue(s.charAt(i)).

22, Binary Tree preorder traversal: Recusion or Interation. Recursion is if null->return, list.add(curr.val), call sameFunction(curr.left, list) and sameFunction(curr.right, list).

Interation: Use Stack. Push right child node first, then left child node.

23, Postorder traversal: similar to 22, use stack, store prev and判断relationship between prev and curr.

24, Inorder traversal:a little bit different from pre and post, only one variable curr.

Traversal都是有两种方法: recursion and interation(stack).

25, Partition list: 所有小于x的element放在前面,大于等于x的放在后面。重点是将大的值挑出来形成一个新的list,并且因为需要delete所以创建两个fake head!最后不要忘记将两个list连接起来,并且抛掉fakeHead。

26, Rotate List: connect tail and head, and note the case n>len, then move len-n%len. Another solution is still two pointers, which has distance n, when the second touches end, the first is the place to terminate.

27, stock: 2 variables min and maxdif, loop over the elements in the array and update these 2 var.

28, Integer to Roman String

I(1), V(5), X(10), L(50), C(100), D(500), M(1000).

第一种方法:从个位到高位,i=1开始增加,在helper method intToCharacter(int n, int i)里面对于i=1 I_V_X,  对于i=2 X_L_C...switch(n) case 1: str+=str1; case 4: str+=str1+str2;...

第二种方法: greedy,

  1. string symbol[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
  2. int value[]=    {1000,900,500,400, 100, 90,  50, 40,  10, 9,   5,  4,   1};
  3. for(int i=0;num!=0;++i)
  4. {
  5. while(num>=value[i])    //这里要注意比如num=3000,那么在i=1上要循环3次print "MMM"
  6. {
  7. num-=value[i];
  8. str+=symbol[i];
  9. }
  10. }
  11. return str;

29,Roman to Integer

对于String逐一字符进行判断,不仅是简单的I->result+1, V->result+5, X->result+10, 还要考虑I在V或X之前的情况,result-1,如果X在C/L之前result-=10..

30, String to int

String中有可能包含space, non-number char, '+', '-'. 所以要trim() String, 判断第一位如果是符号位的话set boolean symbol,对于数字情况即可num = num*10+(c-'0'), 但是要注意提前判断num和Integer.MAX_VALUE/10的关系,if(num>MAX/10 || num==MAX/10 && (c-'0')>7) return MAX or MIN;

31, Merge k sorted lists

http://blog.csdn.net/linhuanmars/article/details/19899259

Use the idea of merge sort, recursive call until only two lists are left.

32, Permutations

两种解法:recursive, or iterate. 练习了不是recursive的方法,最外层是iterate num[] array, 建立新的List<List>> current, 然后iterate result {{1,2}, {2,1}},对于每一个result {1,2},loop j= 0~l.size()+1, 将num[i]插入到不同的j的位置,添加到current中,别忘记再l.remove(j). 在进行下一个i之前,result=new ArrayList<List<>>(current);

CC150采用的是recursive方法。

http://www.cnblogs.com/springfor/p/3888044.html

http://www.programcreek.com/2013/02/leetcode-permutations-java/

33, Pow(x, n)

Recursive call: if(n==0) return 1; if(n==1) return x; double h = power(x, n/2); if(n%2==0) return h*h; else return h*h*x;

34, Valid number

switch(s.charAt(i)) {only consider '+', '-' ,'.', 'e', 'E', '0'~'9', for the others go to default: return false;}, have boolean eFlag, dotFlag, 比如出现过.和e的String就再不能有.出现了。