Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
Solution1: HashMap
public class Solution { public int singleNumber(int[] A) { HashMapmap = new HashMap (); int i = 0; while( i < A.length){ if(map.containsKey(A[i])){ map.put(A[i], map.get(A[i])+1); }else{ map.put(A[i], 1); } i++; } for(Integer key : map.keySet()){ Integer val = map.get(key); if(val != 3) return key; } return 0; } }
Solution2:
public class Solution { public int singleNumber(int[] A) { if( A.length == 1 ) return A[0]; Arrays.sort(A); for( int i = 0 ; i + 2 < A.length; i = i + 3){ if(A[i] == A[i+1] && A[i] == A[i+2]){ continue; }else if( A[i] != A[i+1] ) return A[i]; } return A[A.length - 1]; } }
Solution3: bit manipulation
统计整数的每一位来得到出现次数。如果每个元素重复出现三次,那么每一位出现1的次数也会是3的倍数。统计完成后对每一位进行取余3,那么结果中就只剩下那个出现一次的元素。
只需要对数组进行一次线性扫描,统计完之后每一位进行取余3并且将位数字赋给结果整数,这是一个常量操作(因为整数的位数是固定32位),所以时间复杂度是O(n), constant space。
统计整数的每一位来得到出现次数。如果每个元素重复出现三次,那么每一位出现1的次数也会是3的倍数。统计完成后对每一位进行取余3,那么结果中就只剩下那个出现一次的元素。
只需要对数组进行一次线性扫描,统计完之后每一位进行取余3并且将位数字赋给结果整数,这是一个常量操作(因为整数的位数是固定32位),所以时间复杂度是O(n), constant space。
public class Solution { public int singleNumber(int[] A) { if(A == null || A.length == 0) return 0; int[] digits = new int[32]; for(int i = 0; i < 32; i++) { for(int j = 0; j < A.length; j++) { digits[i] += (A[j] >> i) & 1; } } int res = 0; for(int i = 0; i < 32; i++) { res += (digits[i] % 3) << i; } return res; } }
Reference: http://blog.csdn.net/linhuanmars/article/details/22645599
No comments:
Post a Comment