Analysis of Leetcode Problem Solving Ideas (26) 187-192

  1. Repeated DNA sequences
    Write a function to find all 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.
class Solution {
    
    
public:
    vector<string> findRepeatedDnaSequences(string s) 
    {
    
    
        //对应二进制00, 01, 10, 11.那么10个组合只要20位就够了。
        unordered_map<char, int> m{
    
    {
    
    'A', 0}, {
    
    'C', 1}, {
    
    'G', 2}, {
    
    'T', 3}};
        vector<string> res;
        bitset<1 << 20> s1, s2; //那么所有组合的值将在0到(1 << 20 - 1)之间
        int val = 0, mask = (1 << 20) - 1; //mask等于二进制的20个1
        //类似与滑动窗口先把前10个字母组合
        for (int i = 0; i < 10; ++i) val = (val << 2) | m[s[i]];
        s1.set(val); //置位
        for (int i = 10; i < s.size(); ++i)
        {
    
    
            val = ((val << 2) & mask) | m[s[i]]; //去掉左移的一个字符再加上一个新字符
            if (s2.test(val)) continue; //出现过两次跳过
            if (s1.test(val))
            {
    
    
                res.push_back(s.substr(i - 9, 10));
                s2.set(val);
            }
            else s1.set(val);
        }
        return res;
    }
};
  1. The best time
    to buy and sell stocks 4 Given an array, its i-th element is the price of a given stock on the i-th day.
    Design an algorithm to calculate the maximum profit you can get. You can complete up to k transactions.
    Note: You cannot participate in multiple transactions at the same time (you must sell the previous stocks before buying again).

This question is solved by dynamic programming. The difference from the previous questions is that k needs to be considered. If K is more support for buying and selling every day, just add up directly, otherwise you need to consider which day is the most cost-effective to sell

class Solution {
    
    
public:
    int maxProfit(int k, vector<int>& prices) {
    
    
        if(!prices.size()) return 0;
        if(k >= prices.size()/2)
        {
    
    
            int maxsumval = 0;
            for(int i = 1; i < prices.size(); i++)
                if(prices[i] > prices[i - 1])
                    maxsumval += prices[i] - prices[i - 1];
            return maxsumval;
        }
        vector<int> dp(k + 1, 0);
        vector<int> v(k + 1, prices[0]);
        for(int i = 1; i < prices.size(); i++)
        {
    
    
            for(int t = 1; t <= k; t++)
            {
    
    
                v[t] = min(v[t], prices[i] - dp[t - 1]);
                dp[t] = max(dp[t], prices[i] - v[t]);  
            }
        } 
        return dp[k];
    }
};


  1. Rotate an array
    Given an array, move the elements in the array k positions to the right, where k is a non-negative number.

First reverse all elements. Then reverse the first k elements, and then reverse the next n-kn−k elements, you can get the desired result.

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        reverse(nums.begin(), nums.end() - k % nums.size());
        reverse(nums.end() - k % nums.size(), nums.end());
        reverse(nums.begin(), nums.end());
    }
};

  1. Reverse Binary Bits Reverse the binary bits of
    a given 32-bit unsigned integer.

First, we divide the original 32 bits into two 16-bit blocks.
Then we divide the 16-bit block into two 8-bit blocks.
Then we continue to divide these blocks into smaller blocks until we reach 1-bit blocks.
In each of the above steps, we merge the intermediate results into an integer as the input for the next step.

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        n = (n >> 16) | (n << 16);
        n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8);
        n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4);
        n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2);
        n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1);
        return n;
    }
};

  1. The number of bits 1
    Write a function, the input is an unsigned integer, and returns the number of digits in the binary expression of '1'

The easiest way is to check it bit by bit

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int ret = 0;
        while(n)        
        {
            if (n & 1) ret++;
            n >>= 1;
        }
        return ret;
    }
};

In binary representation, the least significant 11 in the number nn always corresponds to 00 in n-1n−1. Therefore, the AND operation of nn and n-1n−1 can always change the lowest bit of nn into 00 and keep the other bits unchanged.


class Solution {
public:
    int hammingWeight(uint32_t n) {
        int count = 0;

        while(n > 0)
        {
            n &= (n - 1);
            ++count;
        }

        return count;
    }
};


  1. Count word frequency
    Write a bash script to count the frequency of each word in a text file words.txt.

This question is actually divided into two steps, the first step is a single division, and the second step is to count the divided single times.

Single split can be used awkor catadded to xargsachieve

awk '{for(i=1;i<=NF;i++){print $i}}' words.txt 

cat words.txt | xargs -n1

It is very simple to use the awk command to complete this task. In the process of segmentation, an associative array is used to directly save the number of occurrences of each word

awk '{for(i=1;i<=NF;i++){asso_array[$i]++;}};END{for(w in asso_array){print w,asso_array[w];}}' words.txt

If you use it cat + xargs, you need to use sortand uniqrealize

cat words.txt | xargs -n1 | sort | uniq -c

Final code

awk '{for(i=1;i<=NF;i++){asso_array[$i]++;}};END{for(w in asso_array){print w,asso_array[w];}}' words.txt | sort -rn -k2

cat words.txt | xargs -n1 | sort | uniq -c | sort -rn | awk '{print $2,$1}'

Guess you like

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