时隔一年从新开始剑指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; }