[剑指offer] 搜索算法

发布时间 2023-09-19 22:25:11作者: Vivid-BinGo

JZ53 数字在升序数组中出现的次数

 1 /* 二分左边界 */
 2 public class JZ53_1
 3 {
 4     public static int GetNumberOfK(int[] nums, int k)
 5     {
 6         int left = 0, right = nums.length - 1, mid = -1, res = 0;
 7         while (left <= right)
 8         {
 9             mid = (left + right) / 2;
10             if (nums[mid] >= k) right = mid - 1;
11             else left = mid + 1;
12         }
13         for (right++; right < nums.length && nums[right] == k; right++)
14             res++;
15         return res;
16     }
17 }
18 
19 /* 二分右边界 */
20 public class JZ53_2
21 {
22     public static int GetNumberOfK(int[] nums, int k)
23     {
24         int left = 0, right = nums.length - 1, mid = -1, res = 0;
25         while (left <= right)
26         {
27             mid = (left + right) / 2;
28             if (nums[mid] <= k) left = mid + 1;
29             else right = mid - 1;
30         }
31         for (left--; left >= 0 && nums[left] == k; left--)
32             res++;
33         return res;
34     }
35 }

JZ4 二维数组中的查找

 1 /* 从左下角出发,每次排除一行或一列 */
 2 public class JZ4_1
 3 {
 4     public static boolean Find(int target, int[][] array)
 5     {
 6         int i = array.length - 1, j = 0;
 7         while (true)
 8         {
 9             if (i < 0 || j > array[0].length - 1) return false;
10             if (array[i][j] == target) return true;
11             else if (array[i][j] > target) i--;
12             else j++;
13         }
14     }
15 }
16 
17 /* 递归 */
18 public class JZ4_2
19 {
20     public static boolean Find(int target, int[][] array)
21     {
22         return find(0, 0, array.length - 1, array[0].length - 1, target, array);
23     }
24 
25     public static boolean find(int topLeftX, int topLeftY, int lowRightX, int lowRightY, int target, int[][] array)
26     {
27         if (topLeftX < 0 || topLeftX >= array.length || topLeftY < 0 || topLeftY >= array[0].length) return false;
28         if (lowRightX < 0 || lowRightX >= array.length || lowRightY < 0 || lowRightY >= array[0].length) return false;
29         if (topLeftX > lowRightX || topLeftY > lowRightY) return false;
30         int midX = (topLeftX + lowRightX) / 2, midY = (topLeftY + lowRightY) / 2;
31         if (array[midX][midY] == target) return true;
32         else if (array[midX][midY] > target)
33             return find(topLeftX, topLeftY, midX - 1, lowRightY, target, array) ||
34                     find(midX, topLeftY, lowRightX, midY - 1, target, array);
35 
36         else
37             return find(topLeftX, midY + 1, midX, lowRightY, target, array) ||
38                     find(midX + 1, topLeftY, lowRightX, lowRightY, target, array);
39 
40     }
41 }

JZ11 旋转数组的最小数字

 1 /* 双指针 */
 2 public class JZ11_1
 3 {
 4     public static int minNumberInRotateArray(int[] nums)
 5     {
 6         if (nums[nums.length - 1] > nums[0]) return nums[0];
 7         int i = 0, j = nums.length - 1;
 8         while (nums[i] <= nums[i + 1] && nums[j] >= nums[j - 1])
 9         {
10             i++;
11             j--;
12         }
13         return Math.min(nums[i + 1], nums[j]);
14     }
15 }
16 
17 /* 二分 */
18 public class JZ11_2
19 {
20     public static int minNumberInRotateArray(int[] nums)
21     {
22         int left = 0, right = nums.length - 1, mid = -1;
23         while (left < right)
24         {
25             if (nums[left] < nums[right]) return nums[left];
26             mid = (left + right) / 2;
27             if (nums[mid] > nums[left]) left = mid + 1;
28             else if (nums[mid] < nums[right]) right = mid;
29             else left++;
30         }
31         return nums[left];
32     }
33 }

JZ38 字符串的排列

 1 /* 递归1 */
 2 public class JZ38_1
 3 {
 4     public static HashSet<String> SSet = new HashSet<>();
 5     public static boolean[] vis;
 6 
 7     public static ArrayList<String> Permutation(String str)
 8     {
 9         vis = new boolean[str.length()];
10         Permutation(str, new StringBuilder());
11         return new ArrayList<>(SSet);
12     }
13 
14     public static void Permutation(String str, StringBuilder temp)
15     {
16         if (temp.length() == str.length())
17         {
18             SSet.add(temp.toString());
19             return;
20         }
21         for (int i = 0; i < str.length(); i++)
22         {
23             if (vis[i]) continue;
24             vis[i] = true;
25             temp.append(str.charAt(i));
26             Permutation(str, temp);
27             temp.deleteCharAt(temp.length() - 1);
28             vis[i] = false;
29         }
30     }
31 }
32 
33 /* 递归2 */
34 public class JZ38_2
35 {
36     public static HashSet<String> res = new HashSet<String>();
37 
38     public ArrayList<String> Permutation(String str)
39     {
40         Permutation(str.toCharArray(), 0);
41         return new ArrayList<>(res);
42     }
43 
44     public void Permutation(char[] strArr, int begin)
45     {
46         if (begin == strArr.length - 1)
47             res.add(String.valueOf(strArr));
48         else
49         {
50             for (int i = begin; i < strArr.length; i++)
51             {
52                 swap(strArr, begin, i);
53                 Permutation(strArr, begin + 1);
54                 swap(strArr, begin, i);
55             }
56         }
57     }
58 
59     public void swap(char[] strArr, int a, int b)
60     {
61         char temp = strArr[a];
62         strArr[a] = strArr[b];
63         strArr[b] = temp;
64     }
65 }

JZ44 数字序列中某一位的数字

 1 /* 模拟 */
 2 public class JZ44_1
 3 {
 4     public static int findNthDigit(int n)
 5     {
 6         long t = 9, s, y, num, idx = 1, N = n;
 7         if (N < 10) return (int) N;
 8         N--;
 9         while (N >= t* idx)
10         {
11             N = N - t * idx;
12             t *= 10;
13             idx++;
14         }
15         s = N / idx;
16         y = N % idx;
17         num = t / 9 + s;
18         return ("" + num).charAt((int) y) - '0';
19     }
20 }