時隔一年從新開始劍指offer,爭取月底以前作完劍指吧,作個小記錄。java
能夠用HashMap,比較簡單,在評論區看到一種比較好的辦法,記錄一下數組
public int findRepeatNumber(int[] nums) { int n = nums.length; for (int i = 0;i < n;i ++){ int cur = nums[i]; if(cur < 0){ cur = cur + n; } if(nums[cur]<0){ return cur; } nums[i] = nums[i] - n; } return -1; }
public String replaceSpace(String s) { StringBuilder sb = new StringBuilder(); for (char c : s.toCharArray()){ if(c==' ') { sb.append("%20"); }else{ sb.append(c); } } return sb.toString(); }
用棧就好了app
public int[] reversePrint(ListNode head) { Stack<ListNode> stack = new Stack<>(); int count = 0; while (head!=null) { stack.push(head); head = head.next; count++; } int[] result = new int[count]; count = 0; while (!stack.isEmpty()) { result[count++] = stack.pop().val; } return result; }
class CQueue { /** * 前 * */ private Stack<Integer> s1; /** * 後 * */ private Stack<Integer> s2; public CQueue() { s1 = new Stack<>(); s2 = new Stack<>(); } public void appendTail(int value) { s2.push(value); } public int deleteHead() { if (!s1.isEmpty()){ return s1.pop(); } while(!s2.isEmpty()) { s1.push(s2.pop()); } return s1.isEmpty()?-1:s1.pop(); } }
簡單dpui
public static int fib(int n) { if(n<=1) { return n; } int[] nums = new int[n+1]; nums[0] = 0; nums[1] = 1; for (int i = 2;i <= n;i++) { nums[i] = nums[i-1]+nums[i-2]; } return nums[n]; }
和上面相似code
public static int numWays(int n) { if(n==0||n==1) { return 1; } int[] v = new int[n+1]; v[0] = 1; v[1] = 1; v[2] = 2; for (int i = 3;i <= n ;i++) { v[i] = (v[i-1]+v[i-2])%(1000000007); } return v[n]; }
轉爲二分查找比較合適,可是須要變通一下。隊列
public static int minArray(int[] numbers) { int left = 0; int right = numbers.length-1; int mid; if(numbers[left]<numbers[right]) { return numbers[left]; } while (left<right) { if(numbers[left]<numbers[right]) { return numbers[left]; } mid = left + (right - left) / 2; if(numbers[mid] < numbers[right]) { right = mid; } else if(numbers[mid] > numbers[right]) { left = mid + 1; } else { right--; } } return numbers[left]; }
第一種辦法,比較容易想到,模擬咱們手動求數字二進制形式的過程便可,不斷取2的模,而後計數,但須要注意的是,這裏n是無符號數,最高位不作符號位,而是數字位,那麼符號右移的時候,須要採用java的>>>來進行運算,由於對於有符號的右移,n爲負數的時候,最高位會補1,反之補0,但這裏n是無符號數,因此這裏只能採起無符號右移,也就是默認補0,此外,對於循環的終止條件,不該該用n>0,由於n可能爲負數。class
public int hammingWeight(int n) { int count = 0; int num = n; while (num != 0 ){ int t = num & 1; count = count + t; num = num >>> 1; } return count; }
第二種辦法比較巧,相比於第一種辦法突出的地方在於,循環次數減小,由於這裏咱們只須要計算1的個數,而其他位數的0咱們並不在意,因此能夠用n&(n-1)來消去最右邊的1,這樣循環次數就變成了1的個數。List
public static int hammingWeight(int n) { int count = 0; int num = n; while (num != 0 ){ int t = num & 1; count = count + t; num = num >>> 1; } return count; }