catalogue
1. Search in two-dimensional array
2. Rotate the minimum number of the array
3. Adjust the array order so that odd numbers precede even numbers
More than half of the number in the array
1. Search in two-dimensional array
Core test points: array correlation, characteristic observation, grasp of time complexity
[description]
In a two-dimensional array (each one-dimensional array has the same length), each row is sorted in ascending order from left to right, and each column is sorted in ascending order from top to bottom. Please complete a function, input such a two-dimensional array and an integer, and judge whether the array contains the integer.
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
Given target = 7, return true.
Given target = 3, false is returned.
Advanced: space complexity O(1), time complexity O(n+m)
Method 1: traverse the entire array to see if there is this number. It returns true but not false.
class Solution { public: bool Find(int target, vector<vector<int> > array) { for(int i=0;i<array.size();++i) { for(int j=0;j<array[0].size();++j) { if(target==array[i][j]) return true; } } return false; } };
The process of normal search is essentially the process of exclusion. If double loop search eliminates one at a time, the efficiency is too low.
Method 2: find a reference value, which has two lower left corners or upper right corners. Take the upper right corner as an example. In the known question, each row is sorted in ascending order from left to right, and each column is sorted in ascending order from top to bottom. Then the number in the upper right corner is the largest in the first row and the smallest in the last column. The number you want to find is smaller than the benchmark value. Exclude the last column. There is no number smaller than the benchmark value in this column, column -; The number searched is larger than the benchmark value. There is no number larger than the benchmark value in this line, line + +; Returns true if found. When the entire array is traversed and not found, false is returned. This excludes one row or column at a time.
Lower left corner: starting from the lower left corner, larger than the lower left corner, column -; Smaller than the lower left corner, OK --.
class Solution { public: bool Find(int target, vector<vector<int> > array) { //Upper right value int i=0; int j=array[0].size()-1; while(i<=array.size()-1&&j>=0) { if(target>array[i][j]) { ++i; } else if(target<array[i][j]) { --j; } else return true; } return false; //Lower left value // int i=array.size()-1; // int j=0; // while(i>=0 && j<array[0].size()) // { // if(target<array[i][j]) // { // i--; // } // else if(target>array[i][j]) // { // j++; // } // else // { // return true; // } // } // return false; // } // } };
2. Rotate the minimum number of the array
Array understanding, binary search, critical condition
[description]
There is a non descending array with length n, such as [1,2,3,4,5]. Rotate it, that is, move the first elements of an array to the end of the array to become a rotating array, such as [3,4,5,1,2], or [4,5,1,2,3]. Excuse me, given such a rotating array, find the minimum value in the array.
Input: [3,4,5,1,2]
Return value: 1
Requirements: space complexity: O(1), time complexity: O(logn)
[algorithm idea]:
The idea of this problem can learn from the dichotomy. Here, the array rotation can regard the array as two parts. The first half is not decreasing (increasing or equal), the second half is not decreasing, and the first half is greater than or equal to the second half.
Therefore, we can define the leftmost subscript left, the rightmost subscript right, and the middle subscript mid (add the left and right subscripts and divide by 2). When the middle value is greater than the left value, it means that the minimum value is in the right half. Update the interval and assign the mid subscript to left; If the middle value is less than the left value, it means that there is a value smaller than the middle value on the left, or the minimum value is itself, because the values on the right are larger than the mid value. Update the interval and assign the mid subscript to right.
Let's write the big box first:
class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { int left=0; int right=rotateArray.size()-1; int mid=(left+right)>>1; while(left<right) { if(rotateArray[mid]>=rotateArray[left]) { left=mid; } else { right=mid; } } return rotateArray[mid]; }
Two situations are considered:
- Array is empty, no data
- The three numbers left, middle and right are equal
lass Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { //Array is empty, return directly if(rotateArray.empty()) { return 0; } //Set left middle right subscript int left=0; int right=rotateArray.size()-1; int mid=(left+right)>>1; //When the left, middle and right numbers are equal, narrow the range and compare them in [left+1,right-1] if(rotateArray[left]==rotateArray[mid] &&rotateArray[mid]==rotateArray[right]) { int result=rotateArray[left]; for(int i=left+1;i<right;++i) { if(result>rotateArray[i]) { result=rotateArray[i]; } } return result; } if(rotateArray[left]<rotateArray[right]) { return rotateArray[left]; } while(left<right) { if(right-left==1) { mid=right; break; } if(rotateArray[mid]>=rotateArray[left]) { left=mid; } else//rotateArray[mid]<rotateArray[left] { right=mid; } mid=(left+right)>>1; } return rotateArray[mid]; } };
3. Adjust the array order so that odd numbers precede even numbers
Core test point: array operation, extended use of sorting idea
[description]:
Enter an integer array and implement a function to adjust the order of numbers in the array so that all odd numbers are in the first half of the array and all even numbers are in the second half of the array.
[idea]:
The even numbers encountered on the left are exchanged with the odd numbers encountered on the right, so that the odd numbers are all on the left and the even numbers are all on the right.
#include <stdio.h> void Swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } void reSort(int a[], int num) { int left = 0; int right = num - 1; while (left<right) { //Even number found, odd number encountered++ while (left<right && a[left] & 1) { ++left; } //Odd number found, even number encountered-- while (left<right && !(a[right] & 1)) { --right; } Swap(&a[left], &a[right]); } } void PrintArr(int a[],int n) { for (int i = 0; i < n; ++i) { printf("%d ", a[i]); } printf("\n"); } int main() { int arr[] = { 3, 2, 4, 5, 1, 2, 4 }; reSort(arr, sizeof(arr) / sizeof(int)); PrintArr(arr,sizeof(arr)/sizeof(int)); }
When we add a condition to ensure that the relative positions between odd and odd, even and even numbers remain unchanged
[idea]: when encountering an odd number, save the odd number and move the previous even number backward until encountering the previous odd number. Here, we use a subscript k to save the odd number storage location and store an odd number K + +. In this way, when the even number moves to greater than k, it will not move, and the position of K will put the saved odd number.
class Solution { public: void reOrderArray(vector<int> &array) { int k=0;//An odd number of subscripts that identify the placed position for(int i=0;i<array.size();++i) { if(array[i]&1)//Odd number { int odd=array[i]; int j=i;//Use j to save the current position of i. If i is used directly, the subsequent i will also be changed while(j>k)//When it is equal to k, it has been traversed to the last even number { array[j]=array[j-1]; --j; } array[k]=odd; k++; } } } };
In this code, we are thinking about what to do with the first odd number. When j is used to save the current position of i, the subscripts of i and K are 0, that is to say, there are no arranged odd numbers in this array, and j will not be greater than k, so directly put the saved odd numbers in their location. The code here can be optimized. Let's work hard.
4. Numbers that appear more than half the times in the array
Core test points: the use of arrays and the design of simple algorithms
[description]:
A number in the array appears more than half the length of the array. Please find this number. For example, enter an array {1,2,3,2,2,2,2,5,4,2} with a length of 9. Since the number 2 appears five times in the array, more than half the length of the array, 2 is output. If it does not exist, 0 is output
Requirements: space complexity: O(1), time complexity: O(n)
Ensure that the array input is not empty and there is a solution
Input: [1,2,3,2,2,2,5,4,2]
Return value: 2
[idea]:
If the number is more than half of the whole array, it will cancel when it encounters different numbers, and encounter the same number + +, so that the last remaining number must be more than half of the number.
class Solution { public: int MoreThanHalfNum_Solution(vector<int> numbers) { //Find the number that appears most first int num=numbers[0]; int count=1;//Record the number of occurrences for(int i=1;i<numbers.size();++i) { //Same + 1 encountered, different - 1 if(num==numbers[i]) { count++; } else { count--; } //If equal to 0, update the num number and set count to 1 if(count==0) { num=numbers[i]; count=1; } } //Determine whether the number is more than half //Traverse the entire array and count whether the number is more than half int countNum=0; for(int i=0;i<numbers.size();++i) { if(num==numbers[i]) { countNum++; } } int half=numbers.size()>>1; if(countNum>half) { return num; } else return 0; } };