Sword finger offer (V): search algorithm

Topic 1: repeated numbers in the array

Method 1: hash table / Set. It's the same way, but there's no easy answer

```class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> dic = new HashSet<>();
for(int num : nums) {
if(dic.contains(num)) return num;
}
return -1;
}
}
```

Method 2: in situ exchange

By traversing the array and making the index of the element correspond to the value one by one through the exchange operation, the corresponding value can be mapped through the index, which is equivalent to the dictionary.

```class Solution {
public int findRepeatNumber(int[] nums) {
int i = 0;
while(i < nums.length) {
//If the index is equal to the corresponding value, skip
if(nums[i] == i) {
i++;
continue;
}
//If a value is traversed, the element values at num [i] and index I are both num [i] when the following formula is equal, that is, a group of duplicate values are found and returned
if(nums[nums[i]] == nums[i]) return nums[i];
int tmp = nums[i];
nums[i] = nums[tmp];
nums[tmp] = tmp;
}
return -1;
}
}
```

Topic 2: search in two-dimensional array

Find a number in the ordered two-dimensional array. The stupid method uses binary search for each row. The time complexity is NlogN, which is no less than N^2 of the violence scheme;

```class Solution {
int[][] matrix;
int n,target;
public boolean findNumberIn2DArray(int[][] matrix, int target) {
this.matrix = matrix;
int m = matrix.length;
if (m==0)return false;
this.n = matrix[0].length;
if (n==0)return false;
this.target = target;
for (int i = 0; i < m; i++) {
if (matrix[i][n-1]<target)continue;
else {
//Judge each line
if (recursionBinarySearch(matrix[i],target,0,matrix[i].length-1)>=0)return true;
}
}
return false;
}
//Perform binary search
int recursionBinarySearch(int[] arr,int key,int low,int high){
if(key < arr[low] || key > arr[high] || low > high){
return -1;
}
int middle = (low + high) / 2;			//Initial intermediate position
if(arr[middle] > key){
//If it is larger than the keyword, the keyword is in the left area
return recursionBinarySearch(arr, key, low, middle - 1);
}else if(arr[middle] < key){
//Smaller than the keyword, the keyword is in the right area
return recursionBinarySearch(arr, key, middle + 1, high);
}else {
return middle;
}
}
}
```

Method 2: similar to tree access, direct call advanced

Idea: start the search from the "root node". If you encounter an element larger than target, you will turn left, otherwise you will turn right to find the target value target.

```class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
int i = matrix.length - 1, j = 0;
//i is reduced to 0 at most, and j is the line length minus one at most
while(i >= 0 && j < matrix[0].length)
{
if(matrix[i][j] > target) i--;
else if(matrix[i][j] < target) j++;
else return true;
}
return false;
}
}
```

Topic 3: rotate the minimum number of the array

The violence method actually ran through, and the time complexity was also very good, but it was not appropriate to do so. The correct answer was to use two-point search

Method 1: Violence Law

```class Solution {
public int minArray(int[] numbers) {
if (numbers.length==0)return 0;
int res=0;
for (int i = 0; i < numbers.length-1; i++) {
if (numbers[i+1]-numbers[i]<0){
res = i+1;
break;
}
}
return numbers[res];
}
}
```

Method 2: binary search

Key points

• The midpoint of each dichotomy is compared with the right boundary
• Reduced interval security when the comparison values are the same
```class Solution {
public int minArray(int[] numbers) {
int i = 0, j = numbers.length - 1;
while (i < j) {
int m = (i + j) / 2;
if (numbers[m] > numbers[j]) i = m + 1;
else if (numbers[m] < numbers[j]) j = m;
else {
int x = i;
for(int k = i + 1; k < j; k++) {
if(numbers[k] < numbers[x]) x = k;
}
return numbers[x];
}
}
return numbers[i];
}
}
```

Title 4: the first character that appears only once

Method 1: use two set s and a character array

```class Solution {
public char firstUniqChar(String s) {
char reschar = ' ';
if (s.length()==0)return reschar;
char[] tem = new char[s.length()];
Set<Character> res = new HashSet<>();
Set<Character> res1 = new HashSet<>();
for (int i = 0; i < s.length(); i++) {
char cur = s.charAt(i);
if (res.contains(cur)){
}
tem[i] = cur;
}
for (int j = 0; j < tem.length; j++) {
if (!res1.contains(tem[j])){
reschar = tem[j];
break;
}
}
return reschar;
}
}
```

Method 2: hash table – > HashMap < character, Boolean > whether a character is saved and whether it appears once is too subtle

```class Solution {
public char firstUniqChar(String s) {
HashMap<Character, Boolean> dic = new HashMap<>();
char[] sc = s.toCharArray();
for(char c : sc)
dic.put(c, !dic.containsKey(c));
for(char c : sc)
if(dic.get(c)) return c;
return ' ';
}
}
```

Method 3: ordered hash table – > LinkedHashMap

Key value pairs in an ordered hash table are sorted in insertion order. Based on this, you can search the first "number of 1 characters" by traversing the ordered hash table.

```class Solution {
public char firstUniqChar(String s) {
//LinkedHashMap is an ordered hash table
Map<Character, Boolean> dic = new LinkedHashMap<>();
char[] sc = s.toCharArray();
for(char c : sc)
dic.put(c, !dic.containsKey(c));
//The access method of hash table is worth learning
for(Map.Entry<Character, Boolean> d : dic.entrySet()){
if(d.getValue()) return d.getKey();
}
return ' ';
}
}
```

Topic 5: find the number I in the sorted array

Use the binary search method to find the left and right boundaries. The key is how to find the left and right boundaries

```class Solution {
public int search(int[] nums, int target) {
// Search right boundary
int i = 0, j = nums.length - 1;
while(i <= j) {
int m = (i + j) / 2;
if(nums[m] <= target) i = m + 1;
else j = m - 1;
}
int right = i;
// If there is no target in the array, it will be returned in advance
if(j >= 0 && nums[j] != target) return 0;
// Search left border right
i = 0; j = nums.length - 1;
while(i <= j) {
int m = (i + j) / 2;
if(nums[m] < target) i = m + 1;
else j = m - 1;
}
int left = j;
return right - left - 1;
}
}
//The above methods are cumbersome
class Solution {
public int search(int[] nums, int target) {
return helper(nums, target) - helper(nums, target - 1);
}
int helper(int[] nums, int tar) {
int i = 0, j = nums.length - 1;
while(i <= j) {
int m = (i + j) / 2;
if(nums[m] <= tar) i = m + 1;
else j = m - 1;
}
return i;
}
}
```

Title 6: missing numbers in 0 ~ n-1

```class Solution {
public int missingNumber(int[] nums) {
int i = 0, j = nums.length-1;
while (i<=j){
int m = (i+j)/2;
if (nums[m]==m)i=m+1;
else j=m-1;
}
return i;
}
}
```

Posted on Fri, 03 Dec 2021 10:55:17 -0500 by baffled_in_UK