Leetcodeの問題解決のアイデアの分析(32)228-234

  1. 概要の間隔
    繰り返し要素のない順序付けられた整数配列を指定すると、配列の範囲の概要を返します。

とても簡単な質問です

class Solution {
    
    
public:
    vector<string> summaryRanges(vector<int>& nums) 
    {
    
    
        vector<string> ans;

        for (int i = 0; i < nums.size(); i++)
        {
    
    
            string str = to_string(nums[i]);
            int pos = i;

            while (i < nums.size() - 1 && nums[i] + 1 == nums[i + 1]) 
            {
    
    
                i++; //数字连续
            }

            if (pos != i) //若有增加
            {
    
    
                str += "->" + to_string(nums[i]);
            }

            ans.push_back(str);
        }
        return ans;
    }
};


  1. モード2を
    見つけるサイズnの配列を指定して、appear n / 3⌋回より多く出現するすべての要素を見つけます。

ムーアの投票により解決されました。マッピング配列が直接使用される場合、スペースの複雑さは要件を満たしていません

/*
时间复杂度为:O(n)
空间复杂度为:O(1)
*/
class Solution {
    
    
public:
    vector<int> majorityElement(vector<int>& nums) {
    
    
        int len = nums.size();
        vector<int>res, cands, cnts;
        if(len == 0){
    
    //没有元素,直接返回空数组
            return res;
        }
        cands.assign(2, nums[0]);
        cnts.assign(2, 0);
        //第1阶段 成对抵销
        for(auto num: nums){
    
    
            bool flag = false;
            for(int i = 0; i < cands.size(); ++i){
    
    
                if(num == cands[i]){
    
    
                    ++cnts[i];
                    flag = true;
                    break;
                }
            }
            if(!flag){
    
    
                bool flag2 = false;
                for(int j = 0; j < cands.size(); ++j){
    
    
                    if(cnts[j] == 0){
    
    
                        flag2 = true;
                        cands[j] = num;
                        cnts[j]++;
                    }
                }
                if(!flag2){
    
    
                    for(int j = 0; j < cnts.size(); ++j){
    
    
                        --cnts[j];
                    }
                }
            }
        }

        //第2阶段 计数 数目要超过三分之一
        cnts[0] = cnts[1] = 0;
        if(cands[0] == cands[1])
            cands.pop_back();
        for(auto num:nums){
    
    
            for(int i = 0; i < cands.size(); ++i){
    
    
                if(cands[i] == num){
    
    
                    ++cnts[i];
                    break;
                }
            }
        }
        for(int i = 0; i < cands.size(); ++i){
    
    
            if(cnts[i] > len / 3){
    
    
                res.push_back(cands[i]);
            }
        }
        return res;
    }
};


  1. バイナリ検索ツリーのK番目に小さい要素バイナリ検索ツリーが与えられた場合、関数kthSmallestを記述して、その中でk番目に小さい要素を見つけます。

最も簡単な方法は、再帰または反復を使用して中位のトラバーサルを配置することです。k番目の要素を取得するだけです。その中で、反復はk番目のものを見つけ、すぐに戻るのを停止できるため、反復は再帰よりも優れています。


class Solution {
    
    

    int m_cnt = 0, m_ret = 0;

public:
    int kthSmallest(TreeNode* root, int k) 
    {
    
    
        __midOrder(root, k);
        return m_ret;
    }

private:
    void __midOrder(TreeNode *root, int k)
    {
    
    
        if (root == NULL) return;

        __midOrder(root->left, k);
        m_cnt++;
        if (m_cnt == k) m_ret = root->val;
        __midOrder(root->right, k);
    }
};

class Solution {
    
    

    int m_cnt = 0, m_ret = 0;

public:
    int kthSmallest(TreeNode* root, int k) 
    {
    
          
        return __midOrder(root, k);
    }

private:
    int __midOrder(TreeNode *root, int k)
    {
    
    
        stack<TreeNode *> s;
        TreeNode *cur = root;
        while (s.size() || cur)
        {
    
    
            while (cur)
            {
    
    
                s.push(cur);
                cur = cur->left;
            }
            cur = s.top();
            s.pop();
            m_cnt++;
            if (m_cnt == k) return cur->val;
            cur = cur->right;
        }
        return 0;
    }
};
  1. 2のべき乗は
    簡単な質問です
class Solution {
    
    
public:
    bool isPowerOfTwo(int n) {
    
    
        if (n <= 0) return false;
        while (n > 1)
        {
    
    
            if (n % 2 != 0)
                return false;
            else 
                n = n / 2;
        }
        return true;
    }
};
  1. スタックでキューを実装する

前のキューと同様に、必要なスタックは1つだけです。

class MyQueue {
    
    
public:
    stack<int> inStack;
    stack<int> outStack;
    
    MyQueue() {
    
    

    }
    
    void push(int x) {
    
    
        inStack.push(x);
    }
    
    int pop() {
    
    
        cheak();
        int a=outStack.top();
        outStack.pop();
        return a;
    }

    int peek() {
    
    
        cheak();
        return outStack.top();
    }
    

    bool empty() {
    
    
        return inStack.empty()&&outStack.empty();
    }

    void cheak()
    {
    
    
        if(outStack.empty())
        {
    
    
            while(!inStack.empty())
            {
    
    
                outStack.push(inStack.top());
                inStack.pop();
            }

        }
    }
};

/*
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */
  1. 数1の数
    整数nが与えられた場合、n以下のすべての非負整数における数1の出現数を計算します。
    Iは1からnまでトラバースされ、各反復の10倍展開i はビット数を
    (n/(i*10))∗i示し(i*10)ます。
    min(max((n mod (i*10)} )-i+1, 0), i)})追加の桁が必要な桁の(i*10)1 の数を示します
class Solution {
    
    
public:
int countDigitOne(int n)
{
    
    
    int countr = 0;
    for (long long i = 1; i <= n; i *= 10) {
    
    
        long long divider = i * 10;
        countr += (n / divider) * i + min(max(n % divider - i + 1, 0LL), i);
    }
    return countr;
}
};

  1. 回文リンクリスト
    リンクリストが回文リンクリストかどうか判断してください。この問題をO(n)時間の複雑さとO(1)空間の複雑さで解決できますか?

スペースの複雑さO(1)は、スタックストレージまたは再帰検索を使用できないことを示しています。したがって、ここでのアプローチは、最初に高速ポインタと低速ポインタを使用して中間ノードを取得し、高速ポインタと低速ポインタの移動中に前半を逆にし、次に後半と前半を比較することです。値が等しいかどうか。中間ノードのパリティの判断に注意してください

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    bool isPalindrome(ListNode* head) {
    
    
        if(!head || !head->next)
            return 1;
        ListNode *fast = head, *slow = head;
        ListNode *p, *pre = NULL;
        while(fast && fast->next){
    
    
            p = slow;
            slow = slow->next;    //快慢遍历
            fast = fast->next->next;

            p->next = pre;  //翻转
            pre = p;
        }
        if(fast)  //奇数个节点时跳过中间节点
            slow = slow->next;

        while(p){
    
           //前半部分和后半部分比较
            if(p->val != slow->val)
                return 0;
            p = p->next;
            slow = slow->next;
        }
        return 1;
    }
};

おすすめ

転載: blog.csdn.net/u013354486/article/details/107096099