lintcode--剑指offer---31--40道

(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 };
View Code

 (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 }
View Code

 (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 }
View Code

 (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 }
View Code

(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 }
View Code

(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 };
View Code

(37)Search for a Range

 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 }
View Code

(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 }
View Code

(39)Single Number

 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 }
View Code

 (40)Lowest Common Ancestor

 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 }
View Code
原文地址:https://www.cnblogs.com/muziyueyueniao/p/6945638.html