Leetcode problem-solving ideas analysis (34) 268-283

  1. Missing numbers
    Given a sequence containing n numbers in 0, 1, 2, …, n, find the number in 0… n that does not appear in the sequence.

XOR one by one, the missing numbers are those that don’t appear

class Solution {
    
    
public:
    int missingNumber(vector<int>& nums) {
    
    
    int res = nums.size();
    for(int i = 0; i < nums.size(); ++i)
        res = res ^ i ^ nums[i];            // a^b^b = a;
    return res ;
    }
};

  1. Integer conversion English representation
    Convert non-negative integer to its corresponding English representation

This question is actually not difficult, it is to list all the possibilities and combine them, and add spaces

class Solution {
    
    
public:
    vector<string>num1 = {
    
    "","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten",
                        "Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen","Twenty"};
    vector<string>num2 = {
    
    "","","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"};
    vector<string>num3 = {
    
    "Hundred","Thousand","Million","Billion"};//前面增加空字符串,方便单词数字与下标对应
    
    string numberToWords(int num) {
    
    
        if(num == 0)return "Zero";//单独考虑0
        string res = helper(num); 
        res.erase(0,1);
        return res; 
    }

    string helper(int num){
    
    
        if(num == 0){
    
    
            return "";
        }
        if(num<20){
    
    
            return " " + num1[num];
        }
        if(num<100){
    
    
            return " "+num2[num/10] + helper(num%10);
        }
        if(num < 1000){
    
    
            return helper(num/100)+" "+num3[0]+helper(num%100);
        }
        for(int i = 1; i <= 3; i++){
    
    
            if(num < pow(1000,i+1)){
    
    
                return helper(num/(int)pow(1000,i))+ " " + num3[i] + helper(num%(int)pow(1000,i));
            }
        }
        return "";
    }
};


  1. The H index
    is an array of the number of times a researcher's paper has been cited (the number of times the researcher has been cited is a non-negative integer). Write a method to calculate the researcher's h index.
    Definition of h index: h stands for "high citations". The h index of a researcher refers to his (her) (out of N papers) with a total of h papers that have been cited at least h times. (The remaining N-h papers are cited no more than h times.)

According to the meaning of the question, it is meaningless for the number of citations to be greater than N, and the maximum is N. So here can be sorted by counting and packed in different buckets. What we need is h greater than or equal to h, that is, the total number of the next few buckets is greater than or equal to the number of the bucket.

class Solution {
    
    
public:
    int hIndex(vector<int>& citations) {
    
    
        int n = citations.size();
        vector<int> bucket(n + 1, 0);
        for (int i = 0; i < n ; i++)
        {
    
    
            if (citations[i] >= n)
                bucket[n]++;
            else 
                bucket[citations[i]]++;
        }
        int ret = 0;
        for (int i = n; i >= 0; i--)
        {
    
    
            if (ret < i)
            {
    
    
                if (ret + bucket[i] < i)
                    ret += bucket[i];
                else 
                    ret = i;
            }
            else 
                break;
        }
        return ret;
    }
};
  1. The first wrong version
    By calling the bool isBadVersion(version) interface to determine whether the version number version is wrong in the unit test. Implement a function to find the first wrong version. You should minimize the number of API calls.

Typical binary search, the only trap is to note that mid may exceed the numerical limit

// The API isBadVersion is defined for you.
// bool isBadVersion(int version);

class Solution {
    
    
public:
    int firstBadVersion(int n) {
    
    
        int left = 1, right = n;
        while (left < right)
        {
    
    
            int mid = left + (right - left) / 2;
            if (isBadVersion(mid))
                right = mid;
            else left = mid + 1;
        }
        return left;
    }
};



  1. Perfect square numbers
    Given a positive integer n, find several perfect square numbers (such as 1, 4, 9, 16, …) so that their sum equals n. You need to minimize the number of perfect squares that make up the sum.

This problem is easy to use dynamic programming to solve: the least square number of a number N is the square number of N` that makes up the number + 1, that is, for each N, observe who has the smallest solution from 1 to N-1, then the solution of N It is +1. But we don’t need to observe every number from 1 to N+1, because some combinations do not satisfy N = IxI + N'. For example, 12 = 2+N' is not needed because 2 is not The square of a certain number. So the scope of our observation should be greatly reduced.

class Solution {
    
    
public:
    int numSquares(int n)
    {
    
    
        vector<int> result(n+1, 0x7FFFFFFF); // 每个数的最优解都存在result数组里
        result[0] = 0;
        for (int i = 1; i <= n; i++){
    
    
            for(int j = 1; i - j * j >= 0 ; j++) {
    
      // 观察比N小的数,且符合N = IxI + N'的数值
                result[i] = min(result[i], result[i - j * j] + 1); // 把最优解(最小值)+ 1 写入result
            }
        }
        return result[n];
    }
};
  1. Add an operator to the expression.
    Given a string containing only numbers 0-9 and a target value, add a binary operator (not unary) +,-or * between the numbers, and return all expressions that can get the target value formula.

It is solvable using the backtracking method. The more troublesome thing is to consider many details, such as multiplication has higher priority than addition and subtraction. There are four operations: 1. Add a plus sign. 2. Add a minus sign. 3. Add the multiplication sign. 4. Append the next number to form a larger operand. In order to calculate the value of the expression immediately while obtaining the string, some intermediate values ​​need to be maintained during the algorithm.

typedef long long LL;
class Solution {
public:
    vector<string> res;
    string path;
    vector<string> addOperators(string num, int target) {
        if(num == ""){
            return {};
        }
        dfs(0,0,1,num[0] - '0',1,num.size(),target,num);
        return res;
    }

    void dfs(int idx,LL pre,LL left,LL operand,int sign,int n,int target,string& num){
        //查看串尾是否运算符来判断当前数字是否操作数的首位
        bool isBeg = path.empty() || path.back() < '0'; 

        path += num[idx];
        if(idx == n - 1){
            if(pre + sign * left * operand == target){
                res.emplace_back(path);
            }
        }else{
            int next_num = num[idx + 1] - '0';
            string old_path = path;
            //追加数字时不能形成有前导0的情况
            if(!(isBeg && num[idx] == '0')){  
                dfs(idx + 1,pre,left,operand * 10 + next_num,sign,n,target,num);
                path = old_path;
            }
            path += '+';
            dfs(idx + 1,pre + sign * left * operand,1,next_num,1,n,target,num);
            path = old_path;

            path += '-';
            dfs(idx + 1,pre + sign * left * operand,1,next_num,-1,n,target,num);  
            path = old_path;

            path += '*';
            dfs(idx + 1,pre,left * operand,next_num,sign,n,target,num);
        }
    }
};


  1. Move zeros
    Given an array nums, write a function to move all zeros to the end of the array while maintaining the relative order of non-zero elements.

The easiest way is to traverse from beginning to end, delete 0 and add it to the end, which can be easily solved by using stl. A better approach is to use double pointers. When we encounter a non-zero element, we need to swap the elements pointed to by the current pointer and the slow pointer, and then advance the two pointers. If it is a zero element, we only advance the current pointer.

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int cnt = 0;
        vector<int>::iterator iter = nums.begin();
        while (iter != nums.end())
        {
            if (*iter == 0)
            {
                cnt++;
                iter = nums.erase(iter);
            }
            else iter++;
        }
        for (int i = 0; i < cnt; i++)
            nums.push_back(0);

        return;
    }
};
class Solution {
public:
    void moveZeroes(vector<int>& nums) 
    {
        for (int i = 0, cur = 0; cur < nums.size(); cur++) 
        {
            if (nums[cur] != 0) 
            {
                swap(nums[i++], nums[cur]);
            }
        }
    }
};

Guess you like

Origin blog.csdn.net/u013354486/article/details/107548849