This article is (Lesson 18) linear enumeration (II) - Introduction to statistical method For the solutions of the exercises involved after class, post to record your understanding of these questions and ideas in the process of doing questions. If there are mistakes, you are welcome to criticize and correct them.
Before we start, congratulations to EDG! Fight hard for five innings to win the championship trophy for LPL.
OK, let's start today's brush questions.
1. The number of statistical digits is even
Title: give you an integer array nums, please return the number of even digits.
Main idea: you can take the number of digits by using string or mathematical method.
code:
class Solution { public: //Use the string to get the number of digits // bool bitIsEven(int n){ // string s=to_string(n); // return s.size()%2==0? true : false; // } //Take the number of digits by mathematical method bool bitIsEven(int n){ int bit=0; while(n){ n/=10; bit++; } return bit%2==0? true:false; } int findNumbers(vector<int>& nums) { int ans=0; for(auto num:nums){ if(bitIsEven(num)){ ans++; } } return ans; } };
2. Single element in ordered array
Title: given an ordered array containing only integers, each element will appear twice, and only one number will appear once. Find out this number.
Main idea: using XOR operation, the XOR of two identical numbers is 0. XOR all the numbers in the array to get the unique number.
code:
class Solution { public: int singleNonDuplicate(vector<int>& nums) { int ans=0; for(auto num:nums){ ans^=num; } return ans; } };
3. Adjust the array order so that odd numbers precede even numbers
Title: 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.
Main idea: use double pointers to traverse from head to tail to the middle. When the number in front is odd, the left pointer moves to the right; When the following number is even, the right pointer moves left; Swap two numbers in the current even odd time. Finally, the result array is returned.
Pointer:
class Solution { public: vector<int> exchange(vector<int>& nums) { int i=0,j=nums.size()-1; while(i<j){ if(nums[i]%2==0 && nums[j]%2==1){ nums[i]=nums[i]+nums[j]; nums[j]=nums[i]-nums[j]; nums[i]=nums[i]-nums[j]; i++; j--; } else if(nums[i]%2==1){ i++; }else if(nums[j]%2==0){ j--; } } return nums; } };
4. Find the middle position of the array & find the central subscript of the array
Title: give you an integer array nums with subscript starting from 0. Please find the leftmost middle position middleIndex. The middle position is the left sum of the position in the array, which is equal to the right sum. Treat the left and right sum of the left boundary and the right boundary as 0.
Main idea: first find the sum of the array, traverse each number from scratch, and calculate the sum leftSum of the left part of the current position i. when leftSum = sum num [i] - leftSum (i.e. 2 * leftSum + num [i] = sum), this position is the required intermediate position.
code:
class Solution { public: int findMiddleIndex(vector<int>& nums) { int sum=accumulate(nums.begin(),nums.end(),0); int leftSum=0; for(int i=0;i<nums.size();i++){ if(2*leftSum+nums[i]==sum){ return i; } leftSum+=nums[i]; } return -1; } };
5. Delete duplicates in the ordered array
Title: give you an ordered array nums. Please delete the repeated elements in place, so that each element appears only once, and return the new length of the deleted array.
Main idea: use fast and slow pointers. Fast pointers are used to traverse each number, and slow pointers are used to move non repeating numbers forward.
code:
class Solution { public: int removeDuplicates(vector<int>& nums) { int i=1,j=1; if(nums.size()==0){ return 0; } while(j<nums.size()){ if(nums[j]!=nums[j-1]){ nums[i]=nums[j]; i++; } j++; } return i; } };
6. Binary prefix divisible by 5
Title: given an array A composed of several 0 and 1. We define N_i: The ith subarray from A[0] to A[i] is interpreted as A binary number (from the most significant bit to the least significant bit). Returns the Boolean list answer, only when n_ When I can be divided by 5, the answer[i] is true, otherwise it is false.
Main idea: traverse the array, use the temp variable, and use the accumulation formula temp = temp * 2 + num [i] to represent the binary value represented by the currently traversed sub array. For example, for num = [1,1,1] temp = 0, there are
When i=0, temp=0*2+1=1
When i=1, temp=1*2+1=3
When i=2, temp=3*2+1=7
Then it loops continuously to determine whether it can be divided by 5, and stores the result in the ans array.
It should be noted that because the code adopts the accumulation method, it may overflow. The overflow occurs in the temp2 part of the formula temp = temp2 + num [i], so it can take the remainder of 5 to prevent overflow. I have learned before, (ab)%c=(a%c)(b%c)%c, so temp = temp * 2 + num [i] = ((temp% 5) * 2)% 5 + num [i].
Why is this OK? Take 14 for example, 14 + 1 = (72) + 1 = 15 can be divided by 5, (7% 52)% 5 + 1 = 5 can be divided by 5, that is, if temp2 + num [i] can be divided by 5, then (temp2)% 5 + num [I] can also be divided by 5.
code:
class Solution { public: vector<bool> prefixesDivBy5(vector<int>& nums) { int temp=0; vector<bool> ans; for(int i=0;i<nums.size();i++){ temp=((temp%5)*2)%5+nums[i]; if(temp%5==0){ ans.push_back(true); } else{ ans.push_back(false); } } return ans; } };
7. The smallest integer divisible by k
Title: given a positive integer k, you need to find the smallest positive integer N containing only the number 1 that can be divided by K. Returns the length of n. If no such n exists, - 1 is returned.
code:
class Solution { public: int smallestRepunitDivByK(int k) { if(k%2==0 || k%5==0){ return -1; } int ans=1,temp=1; while(temp%k){ temp%=k; //Prevent overflow temp=temp*10+1; ans++; } return ans; } }; //Enumeration method
8. Which continuous substring is longer
Title: give you a binary string s. If the longest continuous substring composed of 1 in the string is strictly longer than the longest continuous substring composed of 0, return true; Otherwise, false is returned.
Main idea: traverse the array, count the length of continuous 1 and 0 respectively, and finally compare them.
code:
class Solution { public: bool checkZeroOnes(string s) { int m=0,n=0,one=0,zero=0; for(int i=0;i<s.size();i++){ if(s[i]=='1'){ m++; if(i!=s.size()-1 && s[i]!=s[i+1]){ one=max(one,m); m=0; } }else{ n++; if(i!=s.size()-1 && s[i]!=s[i+1]){ zero=max(zero,n); n=0; } } } one=max(one,m); zero=max(zero,n); return one>zero; } };