• Leetcode刷题第三期Week1——模拟


    题目列表来自yxc大佬的AcWing Leetcode提高班第三期

    Leetcode 263 Ugly Number

    注意:特别地,1是Ugly Number

    没什么要注意的,三个循环搞定

    class Solution {
    public:
        bool isUgly(int num) {
            if(num <= 0)
                return false;
            while(num % 2 == 0)
                num = num / 2;
            while(num % 3 == 0)
                num = num / 3;
            while(num % 5 == 0)
                num = num / 5;
            return num == 1;
        }
    };

    Leetcode 67 Add Binary

    这题让我想起了高精度,权当是复习一下C++ 的字符串处理吧

    class Solution {
    public:
        string addBinary(string a, string b) {
            char c[100];
            memset(c, '', sizeof(c));
            if(a.size() < b.size()) swap(a, b);
            reverse(a.begin(), a.end());
            reverse(b.begin(), b.end());
            int carry = 0;
            for(int i = 0; i < b.size(); i++) {
                int temp = carry + a[i] - '0' + b[i] - '0';
                if(temp >= 2) {
                    temp -= 2;
                    carry = 1;
                } else {
                    carry = 0;
                }
                c[i] = temp + '0';
            }
            for(int i = b.size(); i < a.size(); i++) {
                int temp = carry + a[i] - '0';
                if(temp >= 2) {
                    temp -= 2;
                    carry = 1;
                } else {
                    carry = 0;
                }
                c[i] = temp + '0';
            }
            if(carry == 1) c[a.size()] ='1';    //注意:这里需要处理一下最高位的进位1(如果有的话)
            string result = c;
            reverse(result.begin(), result.end());
            return result;
        }
    };

    algorithm头文件中提供了swap reverse sort三个常用函数

    memset是cstring头文件中提供的

    yxc大佬给的wp的循环让人觉得非常精妙,这里也放一下,学习学习

    总体思路是使用一个t不断地承接接下来要相加的两个数,然后每次除2即可,不用像我一样单独处理carrry和判断当前结果temp是否超过2了

    string res;
    int k = 0;
    while (k < b.size())
    {
      t += a[k] - '0' + b[k] - '0';
      res += to_string(t&1);
      t /= 2;
      k ++ ;
    }

    顺带一提,评论区有人用python写了个一行的,这里放一下,以示对python的尊敬

    return bin(int(a,2)+int(b,2))[2:]

     Leetcode 504 Base 7

    普普通通的进制转换,写就是了

    class Solution {
    public:
        string convertToBase7(int num) {
            if(num == 0) return "0";
            int num2 = num;
            if(num < 0) {
                num = -num;
            }
            string result;
            while(num != 0) {
                result += num % 7 + '0';
                num /= 7;
            }
            reverse(result.begin(), result.end());
            if(num2 < 0) result = "-" + result;
            return result;
        }
    };

    Leetcode 54 Spiral Matrix

    这题是个最简单的推公式题,但是不知道为啥这题卡了这么久,简直有毒(菜没人权),matrix可能为空,可能为n*1的形式,这两个情况都导致我最开始的代码有问题:matrix为空在开头特判;matrix为3*3的时候,如果每个方向上的终止条件都是<,不是<=,最中间的5将没有人能够够到;最终变成了如下的代码:前三个方向都是<=,每个方向结束后立即比对一次count是否超过了总数,一旦超过了,立刻停止循环,感觉写的逻辑有点乱

    class Solution {
    public:
        vector<int> spiralOrder(vector<vector<int> >& matrix) {
            vector<int> result;
            int m = matrix.size();
            if(m == 0) {
                return result;
            }
            int n = matrix[0].size();
            int count = 0;                  //计数器
            int number = 0;                 //第几圈
            while(count <= m*n) {
                for(int i = number; i <= n - 1 - number; i++) {
                    //left to right
                    result.push_back(matrix[number][i]);
                    count++;
                }
                if(count >= m * n) break;
                for(int i = number + 1; i <= m - 1 - number; i++) {
                    //up to down
                    result.push_back(matrix[i][n-1-number]);
                    count++;
                }
                if(count >= m * n) break;
                for(int i = n-number-2; i >= number; i--) {
                    //right to left
                    result.push_back(matrix[m-1-number][i]);
                    count++;
                }
                if(count >= m * n) break;
                for(int i = m-number-2; i > number; i--) {
                    //down to up
                    result.push_back(matrix[i][number]);
                    count++;
                }
                if(count >= m * n) break;
                number++;
            }
            return result;
        }
    };

    评论区很多人采取了四对0 +1 -1组合的方式来转换坐标,只要当前的组合(比如说0, +1)还能继续往前,那就继续,否则就换到下一个组合

    这种方案的代码示例如下(来自yxc大佬)

    class Solution {
    public:
        vector<int> spiralOrder(vector<vector<int>>& matrix) {
            if (matrix.empty()) return vector<int>();
            int n = matrix.size(), m = matrix[0].size();
            vector<vector<bool>> st(n, vector<bool>(m, false));
            int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
            int x = 0, y = 0, d = 0;
            vector<int> res;
            for (int i = 0; i < n * m; i ++ )
            {
                int a = x + dx[d], b = y + dy[d];
                if (a < 0 || a >= n || b < 0 || b >= m || st[a][b])
                {
                    d = (d + 1) % 4;
                    a = x + dx[d], b = y + dy[d];
                }
                res.push_back(matrix[x][y]);
                st[x][y] = true;
                x = a, y = b;
            }
            return res;
        }
    };
    
    作者:yxc
    链接:https://www.acwing.com/activity/content/code/content/13479/
    来源:AcWing
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    Leetcode 24 Swap Nodes in Pairs

    链表题,草稿打清楚,写过去就好了(注意要把p1->next修改成p2->next才能使链接上)

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* swapPairs(ListNode* head) {
            if(head == NULL || head->next == NULL) {
                return head;
            }
            ListNode *p, *p1, *p2;
            p = head->next;
            head->next = p->next;
            p->next = head;
            head = p;
            p = p->next;
            while(p != NULL && p->next != NULL && p->next->next != NULL) {
                p1 = p->next;
                p2 = p1->next;
                p->next = p2;
                p1->next = p2->next;
                p2->next = p1;
                p = p1;
            }
            return head;
        }
    };

    Leetcode 299 Bulls and Cows

    这个题WA了一次,原因是我最开始在拼字符串的时候是把整型转成了一个char进行拼接的,当计数超过10的时候就会出现错误,于是更改成为了to_string()函数,这个函数来自string头文件

    题的思路没什么,就记得cow要把bull减下去就好了,就一个比较和一个木桶

    class Solution {
    public:
        string getHint(string secret, string guess) {
            //we assume that secret.length == guess.length
            int bull = 0, cow = 0;
            int numbers[2][10] = {0};                  //Wooden barrel
            //0代表secret, 1代表guess
            for(int i = 0; i < secret.size(); i++) {
                bull = bull + (secret[i]==guess[i]);
                numbers[0][secret[i]-'0']++;
                numbers[1][guess[i]-'0']++;
            }
            for(int i = 0; i < 10; i++) {
                cow = cow + min(numbers[0][i], numbers[1][i]);
            }
            string result;
            result = result + to_string(bull) + "A";
            result = result + to_string(cow - bull) + "B";
            return result;
        }
    };

     Leetcode 481 Magical String

    略乱,需要打草稿理清楚变量之间的关系,理清楚就a了

    class Solution {
    public:
        int magicalString(int n) {
            int count = 3;
            vector<int> a;
            a.push_back(1);
            a.push_back(2);
            a.push_back(2);
            if(n <= 0)
                return 0;
            if(n >= 1 && n <= 3)
                return 1;
            int index = 2;
            int result = 1;
            while(count < n) {
                for(int i = 0; i < a[index]; i++) a.push_back(2-(index+1)%2);
                if(index % 2 == 0) result += a[index];
                count = count + a[index];
                index++;
                
            }
            if(count > n && index % 2 == 1) {
                result--;
            }
            return result;
        }
    };

     Leetcode 71 Simplify Path

    用一个栈来维护字符串的信息(头文件<stack>),C++没有字符串split,需要自己实现…………

    class Solution {
    public:
        string simplifyPath(string path) {
            string temp;
            //将原字符串按/进行分割(相当于实现了一个split函数)
            stack<string> b;
            for(int i = 0; i < path.size(); i++) {
                if(path[i] == '/') {
                    if(temp != "") {
                        if(temp == "..") {
                            if(!b.empty())
                                b.pop();
                        }
                        else if(temp != "."){
                            b.push(temp);
                        }
                    }
                    temp = "";
                } else {
                    temp = temp + path[i];
                }
            }
            if(temp != "" && temp != "/") {
                if(temp == "..") {
                    if(!b.empty())
                        b.pop();
                }
                else if(temp != "."){
                    b.push(temp);
                }
            }
            string result;
            while(!b.empty()) {
                result = "/" + b.top() + result;
                b.pop();
            }
            if(result == "")
                result = "/";
            return result;
        }
    };

     评论区老哥的一句话js……服气服气

    var simplifyPath = (path, currPath = []) => {return path.split('/').forEach(item => (item === '..')? currPath.pop() : ((item && item !== '.')? currPath.push(item):'')), '/' + currPath.join('/')}

     Leetcode 12 Integer to Roman

    分情况讨论

    class Solution {
    public:
        string intToRoman(int num) {
            int a[4];
            int i = 0;
            while(num != 0) {           //从个位到千位
                a[i++] = num % 10;
                num /= 10;
            }
            //i是位数
            char tran[4][2] = {'I', 'V', 'X', 'L', 'C', 'D', 'M', ''};
            string result;
            for(int j = 0; j < i; j++) {
                if(a[j] == 0) {
                    continue;
                }
                else if(a[j] == 9) {
                    result = result + tran[j+1][0] + tran[j][0];
                }
                else if(a[j] == 4) {
                    result = result + tran[j][1] + tran[j][0];
                }
                else if(a[j] >= 5) {
                    for(int k = 0; k < a[j] - 5; k++) {
                        result = result + tran[j][0];
                    }
                    result = result + tran[j][1];
                } else {
                    for(int k = 0; k < a[j]; k++) {
                        result = result + tran[j][0];
                    }
                }
            }
            reverse(result.begin(), result.end());
            return result;
        }
    };

    yxc大佬给的思路更为清晰,外层for和内层的while配合的很完美,只要你还足够大就一直减这一级,精妙精妙,这里也贴一下

    class Solution {
    public:
        string intToRoman(int num) {
            int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
            string reps[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
    
            string res;
            for (int i = 0; i < 13; i ++ )
                while(num >= values[i])
                {
                    num -= values[i];
                    res += reps[i];
                }
            return res;
        }
    };
    
    作者:yxc
    链接:https://www.acwing.com/solution/LeetCode/content/101/
    来源:AcWing
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

     Leetcode 68 Text Justification

    先将数据分割成若干行长度小于等于MaxWidth的行(统计长度应该注意把词与词之间的间隔中的空格统计进去)

    如果是最后一行,则只实现左对齐:每个单词之间插入一个空格,行尾插入若干空格,使这一行的总长度是 maxWidth
    如果这一行只有一个单词,则直接在行尾补上空格
    其他情况,则需计算总共要填补多少空格,然后按题意均分在单词之间(左多右少)

    class Solution {
    public:
        vector<string> fullJustify(vector<string>& words, int maxWidth) {
            vector<string> result;
            vector<vector<string> > Array;
            vector<string> temp;
            int length = 0;
            for(int i = 0; i < words.size(); i++) {
                if(length == 0) {
                    //行首不应该有空格
                    length += words[i].size();
                    temp.push_back(words[i]);
                }
                else if(length + 1 + words[i].size() <= maxWidth) {
                    //词与词之间应该有空格
                    length = length + 1 + words[i].size();
                    temp.push_back(words[i]);
                }
                else {
                    //放不开当前这一个了,应该结算
                    Array.push_back(temp);
                    length = words[i].size();
                    temp.clear();
                    temp.push_back(words[i]);
                }
            }
            //结束之后如果temp数组不为空,进行一次额外结算,这一定是最后一行,所以可以特殊处理
            if(temp.size() > 0) {
                Array.push_back(temp);
            }
            //开始拼接字符串,注意:最后一行需要特殊处理,因此单独列出
            for(int i = 0; i < Array.size() - 1; i++) {
                length = 0;
                for(int j = 0; j < Array[i].size(); j++) {
                    length += Array[i][j].size();
                }
                int delta = maxWidth - length;
                int num = Array[i].size() - 1;          //缝隙数目
                string t;
                if(num == 0) {
                    //如果没有缝隙(这一行就这一个单词,我们需要把这个字符串后面全部填上空格)
                    t = Array[i][0];
                    for(int j = 0; j < delta; j++) t += " ";
                    result.push_back(t);
                } else {
                    //缝隙数目大于等于1,均匀分配,左多右少
                    for(int j = 0; j < num; j++) {
                        t = t + Array[i][j];
                        for(int k = 0; k < delta / num; k++) t += " ";  //均匀分配的部分
                        if(j < delta % num) t += " ";                   //左多右少的额外空格
                    }
                    t += Array[i][Array[i].size() - 1];
                    result.push_back(t);
                }
            }
            //开始处理最后一行
            string t;
            length = 0;
            int lastLine = Array.size()-1;
            for(int i = 0; i < Array[lastLine].size()-1; i++) {
                t = t + Array[lastLine][i] + " ";
                length = length + Array[lastLine][i].size() + 1;
            }
            t = t + Array[lastLine][Array[lastLine].size()-1];
            length = length + Array[lastLine][Array[lastLine].size()-1].size();
            int delta = maxWidth - length;
            for(int i = 0; i < delta; i++) {
                t = t + " ";
            }
            result.push_back(t);
            return result;
        }
    };

     Happy Birthday!    hhh

  • 相关阅读:
    Basic knowledge of html (keep for myself)
    科学技术法转成BigDemcial
    SimpleDateFormat
    log4j 配置实例
    R 实例1
    yield curve
    if-else的优化举例
    十二、高级事件处理
    十一、Swing
    十、输入/输出
  • 原文地址:https://www.cnblogs.com/Briddle-ch/p/12346330.html
Copyright © 2020-2023  润新知