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, ‘\0‘, 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‘, ‘\0‘};
        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

原文地址:https://www.cnblogs.com/Briddle-ch/p/12346330.html

时间: 2024-07-28 18:51:00

Leetcode刷题第三期Week1——模拟的相关文章

【leetcode刷题笔记】Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3) + (5 -> 6 ->

【leetcode刷题笔记】Plus One

Given a non-negative number represented as an array of digits, plus one to the number. The digits are stored such that the most significant digit is at the head of the list. 题解:模拟即可,用carries代表进位,当carries=1的时候说明下一位上要加上进位,就一直往前进位,直到某一位可以加1不进位,或者已经到最高位.

【leetcode刷题笔记】ZigZag Conversion

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line:  "PAHNAPLSI

【leetcode刷题笔记】Pascal&#39;s Triangle II

Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3,Return [1,3,3,1]. Note:Could you optimize your algorithm to use only O(k) extra space? 题解:简单的模拟题,每次用answer列表存放上一层的值,用temp列表存放当前层的值,只要计算好temp中需要重新计算的元素的索引范围[1,i-1]

【leetcode刷题笔记】Add Binary

Given two binary strings, return their sum (also a binary string). For example,a = "11"b = "1"Return "100". 题解:简单的二进制加法模拟.a,b的最后以为对齐开始进行加法,用carries保存进位,如果加完后最高位还有进位,那么要在结果的最前面加一个1. 代码如下: 1 public class Solution { 2 public Str

【leetcode刷题笔记】Count and Say

The count-and-say sequence is the sequence of integers beginning as follows:1, 11, 21, 1211, 111221, ... 1 is read off as "one 1" or 11.11 is read off as "two 1s" or 21.21 is read off as "one 2, then one 1" or 1211. Given an

【leetcode刷题笔记】Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

leetcode 刷题之路 63 Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its zig

leetcode 刷题之路 64 Construct Binary Tree from Inorder and Postorder Traversal

Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 给出二叉树的中序遍历和后序遍历结果,恢复出二叉树. 后序遍历序列的最后一个元素值是二叉树的根节点的值,查找该元素在中序遍历序列中的位置mid,根据中序遍历和后序遍历性质,有: 位置mid以前的序列部分为二叉树根节点左子树中