(31)Digit Counts (比较蠢的做法,但是lintcode通过测试了)
1 class Solution { 2 /* 3 * param k : As description. 4 * param n : As description. 5 * return: An integer denote the count of digit k in 1..n 6 */ 7 public int digitCounts(int k, int n) { 8 if (n < 0) { 9 return 0; 10 } 11 int count = 0; 12 for (int i = k; i <= n; i++) { //从k开始计算,免去k之前计算的麻烦 13 count += kCount(k, i); 14 } 15 return count; 16 } 17 public int kCount(int k, int num) { 18 if (num < 0) { 19 return 0; 20 } 21 //由于循环的条件是大于等于0,所以必须把num为0的情况单独拿出来 22 if (k == 0 && num == 0) { 23 return 1; 24 } 25 int count = 0; 26 while (num > 0) { 27 if (num % 10 == k) { 28 count++; 29 } 30 num = num / 10; 31 } 32 return count; 33 } 34 };
(32)Reverse Pairs (进行归并排序,融合的时候记录逆序对)
1 public class Solution { 2 /** 3 * @param A an array 4 * @return total of reverse pairs 5 */ 6 long count = 0; //定义一个成员变量,这样所有的成员函数都可以使用,直接对其进行操作 7 public long reversePairs(int[] a) { 8 //思路:在进行归并排序的时候记录逆序对 9 if (a == null || a.length <= 1) { 10 return 0; 11 } 12 int[] temp = new int[a.length]; 13 mergeDivideSort(a, 0, a.length - 1, temp); 14 return count; 15 } 16 public void mergeDivideSort(int[] a, int start, int end, int[] temp) { 17 //归并排序中的分组以及排序操作,分到都为单个数字 18 if (start >= end) { 19 return; 20 } 21 int mid = start + (end - start) / 2; 22 mergeDivideSort(a, start, mid, temp); 23 mergeDivideSort(a, mid + 1, end, temp); 24 merge(a, start, end, temp); 25 } 26 public void merge(int[] a, int start, int end, int[] temp) { 27 //将两个排序好的数组进行融合,融合的时候记录逆序对 28 int mid = start + (end - start) / 2; 29 //记录逆序对 30 int left = start; 31 int right = mid + 1; 32 for (left = start; left <= mid; left++) { 33 while (right <= end && a[left] > a[right]) { 34 right++; 35 } 36 //由于分的两个组是已经排序好的,那么如果a[left]小于a[right]跳出循环,count加0 37 count += right - (mid + 1); //j为第一个a[left]小于a[right]的位置,之前都大于,即之前都是逆序对 38 } 39 //归并排序的融合部分 40 int leftIndex = start; 41 int rightIndex = mid + 1; 42 int index = start; 43 while (leftIndex <= mid && rightIndex <= end) { 44 if (a[leftIndex] < a[rightIndex]) { 45 temp[index++] = a[leftIndex++]; 46 } else { 47 temp[index++] = a[rightIndex++]; 48 } 49 } 50 while (leftIndex <= mid) { 51 temp[index++] = a[leftIndex++]; 52 } 53 while (rightIndex <= end) { 54 temp[index++] = a[rightIndex++]; 55 } 56 for (int i = start; i <= end; i++) { 57 a[i] = temp[i]; 58 } 59 } 60 }
(33)Kth Largest Element (进行从大到小快速排序的时候计算找第K大的元素)
1 class Solution { 2 /* 3 * @param k : description of k 4 * @param nums : array of nums 5 * @return: description of return 6 */ 7 public int kthLargestElement(int k, int[] nums) { 8 //思路:进行从大到小快速排序的时候计算找第K大的元素 9 if (nums == null || nums.length == 0 || k <= 0) { 10 return 0; 11 } 12 return quickSelect(nums, 0, nums.length - 1, k); 13 } 14 public int quickSelect(int[] nums, int start, int end, int k) { 15 int mid = start + (end - start) / 2; 16 int left = start; 17 int right = end; 18 int pivot = nums[mid]; 19 //快速排序模板 20 while (left <= right) { 21 while (left <= right && nums[left] > pivot) { 22 left++; 23 } 24 while (left <= right && nums[right] < pivot) { 25 right--; 26 } 27 if (left <= right) { 28 int temp = nums[left]; 29 nums[left] = nums[right]; 30 nums[right] = temp; 31 left++; 32 right--; 33 } 34 } 35 //经过快速排序之后只可能有两种情况:第一种right-pivot-left,第二种right-left 36 if (k <= right - start + 1) { 37 return quickSelect(nums, start, right, k); 38 } 39 if (k > left - start) { 40 return quickSelect(nums, left, end, k - (left - start)); 41 } 42 return nums[right + 1]; //nums[left - 1] 43 } 44 }
(34)Reverse Words in a String
1 public class Solution { 2 /** 3 * @param s : A string 4 * @return : A string 5 */ 6 public String reverseWords(String s) { 7 // null 表示没有传string对象, s.length() == 0 表示传了,但是什么也没有、 8 // return "" 表示返回一个空的字符串 return " "表示传了一个空格 9 if (s == null || s.length() == 0) { 10 return ""; 11 } 12 //用空格将字符串分开,如果中间或者前面或者后面有很多空格的话,那么数组中这个元素就为空 13 String[] wordArr = s.split(" "); 14 StringBuilder sb = new StringBuilder(); 15 for (int i = wordArr.length - 1; i >= 0; i--) { 16 if (!wordArr[i].equals("")) { 17 sb.append(wordArr[i]).append(" "); 18 } 19 } 20 return sb.length() == 0 ? "" : sb.substring(0, sb.length() - 1); 21 } 22 }
(35)Rotate String
1 public class Solution { 2 /** 3 * @param str: an array of char 4 * @param offset: an integer 5 * @return: nothing 6 */ 7 public void rotateString(char[] str, int offset) { 8 if (str == null || str.length == 0 ) { 9 return; 10 } 11 int len = str.length; 12 offset = offset % len; 13 int firstEnd = len - offset - 1; 14 int secondStart = firstEnd + 1; 15 //将两部分分别反转,之后再将整个数组反转 16 reverse(str, 0, firstEnd); 17 reverse(str, secondStart, str.length - 1); 18 reverse(str, 0, str.length - 1); 19 } 20 public void reverse(char[] str, int start, int end) { 21 if (str == null || str.length == 0) { 22 return; 23 } 24 while (start < end) { 25 char temp = str[start]; 26 str[start] = str[end]; 27 str[end] = temp; 28 start++; 29 end--; 30 } 31 } 32 }
(36)A + B Problem
1 class Solution { 2 /* 3 * param a: The first integer 4 * param b: The second integer 5 * return: The sum of a and b 6 */ 7 public int aplusb(int a, int b) { 8 while (b != 0) { 9 // 主要利用异或运算来完成 10 // 异或运算有一个别名叫做:不进位加法 11 // 那么a ^ b就是a和b相加之后,该进位的地方不进位的结果 12 // 然后下面考虑哪些地方要进位,自然是a和b里都是1的地方 13 // a & b就是a和b里都是1的那些位置,a & b << 1 就是进位 14 // 之后的结果。所以:a + b = (a ^ b) + (a & b << 1) 15 // 令a' = a ^ b, b' = (a & b) << 1 16 // 可以知道,这个过程是在模拟加法的运算过程,进位不可能 17 // 一直持续,所以b最终会变为0。因此重复做上述操作就可以 18 // 求得a + b的值。 19 int newA = a ^ b; 20 int newB = (a & b) << 1; 21 a = newA; 22 b = newB; 23 } 24 return a; 25 } 26 };
1 public class Solution { 2 /** 3 *@param A : an integer sorted array 4 *@param target : an integer to be inserted 5 *return : a list of length 2, [index1, index2] 6 */ 7 public int[] searchRange(int[] a, int target) { 8 int[] result = new int[2]; 9 result[0] = getFirstTarget(a, target, 0, a.length - 1); 10 result[1] = getLastTarget(a, target, 0, a.length - 1); 11 return result; 12 } 13 public int getFirstTarget(int[] a, int target, int start, int end) { 14 //二分法先寻找第一个target的索引,然后相同的方式寻找第二个target的索引。 15 if (a == null || a.length == 0 || start > end) { 16 return -1; 17 } 18 int mid = start + (end - start) / 2; 19 if (a[mid] == target) { 20 if (mid > 0 && a[mid - 1] != target || mid == 0) { 21 return mid; 22 } else { 23 end = mid - 1; 24 } 25 } else if (a[mid] < target) { 26 start = mid + 1; 27 } else { 28 end = mid - 1; 29 } 30 return getFirstTarget(a, target, start, end); 31 } 32 public int getLastTarget(int[] a, int target, int start, int end) { 33 if (a == null || a.length == 0 || start > end) { 34 return -1; 35 } 36 int mid = start + (end - start) / 2; 37 if (a[mid] == target) { 38 if (mid < a.length - 1 && a[mid + 1] != target || mid == a.length - 1) { 39 return mid; 40 } else { 41 start = mid + 1; 42 } 43 } else if (a[mid] < target) { 44 start = mid + 1; 45 } else { 46 end = mid - 1; 47 } 48 return getLastTarget(a, target, start, end); 49 } 50 }
(38)Maximum Depth of Binary Tree
1 /** 2 * Definition of TreeNode: 3 * public class TreeNode { 4 * public int val; 5 * public TreeNode left, right; 6 * public TreeNode(int val) { 7 * this.val = val; 8 * this.left = this.right = null; 9 * } 10 * } 11 */ 12 public class Solution { 13 /** 14 * @param root: The root of binary tree. 15 * @return: An integer. 16 */ 17 public int maxDepth(TreeNode root) { 18 if (root == null) { 19 return 0; 20 } 21 //加的1是当前节点的深度 22 return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; 23 } 24 }
1 public class Solution { 2 /** 3 *@param A : an integer array 4 *return : a integer 5 */ 6 public int singleNumber(int[] a) { 7 if (a == null || a.length == 0) { 8 return 0; 9 } 10 //由于异或是不同为1,相同为0,那么数组中所有的数字依次异或,相同的异或为 11 //0,0与目标数字异或还未目标数字,任何数字与0异或不变. 12 int i = 1; 13 int temp = a[0]; 14 while (i < a.length) { 15 temp = temp ^ a[i]; 16 i++; 17 } 18 return temp; 19 } 20 }
1 /** 2 * Definition of TreeNode: 3 * public class TreeNode { 4 * public int val; 5 * public TreeNode left, right; 6 * public TreeNode(int val) { 7 * this.val = val; 8 * this.left = this.right = null; 9 * } 10 * } 11 */ 12 public class Solution { 13 /** 14 * @param root: The root of the binary search tree. 15 * @param A and B: two nodes in a Binary. 16 * @return: Return the least common ancestor(LCA) of the two nodes. 17 */ 18 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode node1, TreeNode node2) { 19 //if one of nodes is root, then return this node 20 if (root == null || root == node1 || root == node2) { 21 return root; 22 } 23 //divide: 24 TreeNode left = lowestCommonAncestor(root.left, node1, node2); 25 TreeNode right = lowestCommonAncestor(root.right, node1, node2); 26 //conquer: 27 if (left != null && right != null) { 28 return root; 29 } 30 if (left != null) { 31 return left; 32 } 33 if (right != null) { 34 return right; 35 } 36 return null; 37 } 38 }