Leetcode medium难度顺序题解

被迫重操旧业(?)

再不刷题面试就真要翻车了。。。。
好在medium题难度还比较水,幸亏它不考什么神DP或数据结构或blabla不然我还面个锤子(x)
但是现场写代码还不准出错ATP顶8住啊所以还是练练手感叭。。。。
就,按顺序随便做几个。点中等难度然后按题号排序这样。

2. 两数相加

高精度但是用单向链表。
一开始ATP写的很麻烦,基本思路是先把两个数字重叠的部分相加,然后再单独处理较长的数字多出来的那部分,然后再处理进位这样。一共三个while循环。
但是后来发现好像直接改一下判断条件,如果其中一个数字链表到头了就不要管它,这样就只用一个while就能解决。
(果然年纪大了哭哭)

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *Answer, *now, *newnode;
        int tmp, carrybit = 0;
        Answer = new ListNode(0);
        now = Answer;
        while (l1 != NULL || l2 != NULL){
            tmp = carrybit;
            if (l1 != NULL) tmp += l1->val;
            if (l2 != NULL) tmp += l2->val;
            carrybit = tmp / 10; tmp = tmp % 10;
            now->val = tmp;
            if (l1 != NULL) l1 = l1->next;
            if (l2 != NULL) l2 = l2->next;
            if (l1 != NULL || l2 != NULL || carrybit != 0) {
                newnode = new ListNode(0);
                now->next = newnode; now = newnode;
            }
        }
        if (carrybit != 0) {
            now->val = carrybit;
        }
        return Answer;
    }
};

3.无重复字符的最长子串

\(O(n^2)\)的很好想嘛就直接暴力枚举了。
但是其实显然应该还有更优的做法。。。ATP一开始想对每个字符处理它能延伸的最长区间,但是这样没法很好地处理包含的问题。。。
其实two pointers扫一遍就可以了。每次加入一个新字符的时候移动左端点即可。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int Answer = 0, len = s.size(), ext[200], L = 0;
        memset(ext, -1, sizeof(ext));
        for (int i = 0; i < len; i ++) {
            L = max(L, ext[s[i]] + 1);
            ext[s[i]] = i;
            Answer = max(Answer, i - L + 1);
        }
        return Answer;
    }
};

5. 最长回文子串

manacher板子题。。。(但是我忘了manacher怎么写所以抄的zyf2000的板子1551)
细节问题就是两个字符中间要加分隔符来处理回文中心不在字符上的情况,然后最开头的位置要放一个特殊字符这样就可以避免while循环的时候越界。
之前都是用&#@这样的字符来着但是考虑到LeetCode的尿性,它没说全是小写字母还是不用这些字符了。。于是ATP就把它很麻烦地倒腾到数组里用数字来做了。
最后那个输出结果按理说是可以算一下然后直接用string的substr函数搞的,但是ATP懒得动脑子所以就使用脑死亡做法——一个一个把字符加进去。。。
边界卡了半天。我好菜(

class Solution {
public:
    string longestPalindrome(string s) {
        int len = s.size(), *p, *arr, id = 1, mx = 1;
        string Answer = "";
        arr = new int[2 * len + 10];
        p = new int[2 * len + 10];
        arr[0] = -2;
        for (int i = 0; i < len; i ++) {
            arr[i * 2 + 1] = s[i];
            arr[i * 2 + 2] = -1;
        }
        for (int i = 1; i < 2 * len; i ++) {
            if (mx > i) p[i] = min(p[2 * id - i], mx - i);
            else p[i] = 1;
            while (arr[i - p[i]] == arr[i + p[i]])
                ++ p[i];
            if (i + p[i] > mx) {
                mx = i + p[i]; id = i;
            }
        }
        mx = 0; id = 1;
        for (int i = 1; i < 2 * len; i ++) {
            int val = p[i];
            if (arr[i - p[i]] == -1) val = p[i] - 1;
            if (val > mx){mx = val; id = i;}
        }
        for (int i = id - mx + 1; i <= id + mx - 1; i ++)
            if (arr[i] > 0) Answer.push_back((char)(arr[i]));
        return Answer;
    }
};

6. Z字形变换

我的做法是先算出要用几行几列的数组,然后再一个个填字(究极脑死做法
但是实际上应该可以直接构造答案字符串。只要知道现在正在读第几个Z字形的第几个字符,就可以算出它对应原字符串的哪个位置。这样应该会更快一点。。。

class Solution {
public:
    string convert(string s, int numRows) {
        int cycle = numRows * 2 - 2, len = s.size();
        int numCols, p1, p2;
        bool flag = false;
        string Answer = "";
        if (numRows == 1) return s;
        numCols = len / cycle;
        numCols *= numRows - 1;
        if (len % cycle > 0) numCols += 1;
        if (len % cycle > numRows) numCols += len % cycle - numRows;
        char arr[numRows][numCols];
        p1 = p2 = 0;
        for (int i = 0; i < numRows; i ++)
            for (int j = 0; j < numCols; j ++)
                arr[i][j] = 0;
        for (int i = 0; i < len; i ++) {
            arr[p2][p1] = s[i];
            if (flag == false) {
                if (p2 + 1 < numRows) p2 ++;
                else {p1 ++; p2 --; flag = true;}
            }else {
                if (p2 - 1 >= 0) {p1 ++; p2 --;}
                else {p2 ++; flag = false;}
            }
        }
        for (int i = 0; i < numRows; i ++)
            for (int j = 0; j < numCols; j ++)
                if (arr[i][j] > 0) Answer.push_back(arr[i][j]);
        return Answer;
    }
};

8. 字符串转换整数(atoi)

注意判一下开头的正负号就行了。。越界问题ATP直接用long long搞的(又是脑死做法)

class Solution {
public:
    int myAtoi(string str) {
        int ptr = 0;
        long long Answer = 0, sign = 1;
        const long long MAX = 2147483648LL;
        while (str[ptr] == ' ') ptr ++;
        if (str[ptr] != '+' && str[ptr] != '-' && (str[ptr] < '0' || str[ptr] > '9'))
            return 0;
        if (str[ptr] == '+') {sign = 1; ptr ++;}
        else if (str[ptr] == '-') {sign = -1; ptr ++;}
        while (str[ptr] <= '9' && str[ptr] >= '0') {
            Answer = Answer * 10 + str[ptr] - '0';
            ptr ++;
            if (Answer > MAX) Answer = MAX;
        }
        Answer = Answer * sign;
        if (Answer == MAX) Answer = MAX - 1;
        return (int)Answer;
    }
};

11. 盛水最多的容器

two pointers扫一遍即可。第一个指针在开头,第二个指针在结尾。因为如果缩短x轴长度能增大总容量就一定得排除短板,所以两个指针指向的位置哪个短就先移动哪个。
但是严格证明我不会。。。看了一下别人的题解,大致思路是说排除短板以后不会被扫到的那些解一定不可能是最优解。

class Solution {
public:
    #include <algorithm>
    int maxArea(vector<int>& height) {
        int p1 = 0, p2 = height.size() - 1;
        int Answer = 0;
        while (p1 != p2) {
            Answer = max(Answer, (p2 - p1) * min(height[p2], height[p1]));
            if (height[p2] < height[p1]) p2 --;
            else p1 ++;
        }
        return Answer;
    }
};

12. 整数转罗马数字

这题的关键是总结出整数转罗马数字的规则(x
LeetCode上有人说实际上目标是使用的字母最少,听起来好像有道理。
规则是能用大的就用大的,包括40、90这些特殊数字。但是10,100这些数字可以连续使用多次,40,90这种的就不可以。

class Solution {
public:
    string intToRoman(int num) {
        string Answer = "";
        int ww[13] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
        string st[13] = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"};
        for (int i = 12; i >= 0; i --) {
            if (i % 2 == 1){
                if (num - ww[i] >= 0) {
                    num -= ww[i]; Answer += st[i];
                }
            }else {
                while (num - ww[i] >= 0) {
                    num -= ww[i]; Answer += st[i];
                }
            }
        }
        return Answer;
    }
};

原文地址:https://www.cnblogs.com/FromATP/p/12262984.html

时间: 2024-08-03 11:35:09

Leetcode medium难度顺序题解的相关文章

每日温度(LeetCode Medium难度算法题)题解

LeetCode 题号739中等难度 每日温度 题目描述: 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]. 提示:气温 列表长度的范围是 [1, 30000].每个气温的值的均为华氏度,都是在 [30, 100] 

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】【Python题解】Pascal&#39;s Triangle

Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Return [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 要求输入一个整数,返回一个表示杨辉三角的数组.我的方法是计算通项公式,首先是编写阶乘函数,然后计算C00,C10,C11即可 利用Python 的map嵌套可以很简洁地实现,核心代码只有一行! class So

LeetCode: Longest Common Prefix 题解

Write a function to find the longest common prefix string amongst an array of strings. 题解: 寻找一组字符串的最长公共前缀.  最简单的方法,用一个字符串记录当前最长的公共前缀,然后依次比较.时间复杂度: O(N). 1 class Solution { 2 public: 3 string getPrefix(string a,string b) // 辅助函数用于获取两个字符串的公共前缀 4 { 5 st

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: Roman to Interger 题解

Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. 找到规则即可 罗马数字的表示: I~1 V~5 X~10 L~50 C~100 D~500 M~1000 规则: 基本数字Ⅰ.X .C 中的任何一个,自身连用构成数目,或者放在大数的右边连用构成数目,都不能超过三个:放在大数的左边只能用一个. 不能把基本数字V .L .D 中的任何一

【LeetCode】【Python题解】Best Time to Buy and Sell Stock II

Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). Ho

LeetCode: Permutations II 题解

Given a collection of numbers that might contain duplicates, return all possible unique permutations. For example,[1,1,2] have the following unique permutations:[1,1,2], [1,2,1], and [2,1,1].题解:依旧使用的是DFS的思想. 首先需要遍历输入数组,获取一共有多少种不同的数字,每个数字有多少个. 最简单的方法,

LeetCode: Valid Parentheses 题解

Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]"