LeetCode刷题日记(Day7)

Problem 21. Merge Two Sorted Lists

  • 题目描述
    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

  • 解题思路
    此题较简单,创建一个新的链表 head ,按照以下规则将 l1 或 l2 的元素依次加入到 head 后:

  1. 若 l1->val >= l2->val,则将 l2->val 加入到 head 后;
  2. 若 l1->val < l2->val,则将 l1->val 加入到 head 后;
  3. 若其中一个链表已遍历完毕,则将另一个链表加入到 head 后。
  • 代码实现
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *head = new ListNode(0);
        ListNode *cur = head;
        while(l1 && l2){
            if (l1->val >= l2->val){
                cur -> next = l2;
                l2 = l2 -> next;
            }
            else{
                cur -> next = l1;
                l1 = l1 -> next;
            }
            cur = cur -> next;
        }
        cur -> next = l1? l1 : l2;
        return head -> next;
    }
};

Problem 22. Generate Parentheses

  • 题目描述
    Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
    For example, given n = 3, a solution set is:

    [
      "((()))",
      "(()())",
      "(())()",
      "()(())",
      "()()()"
    ]
    
  • 解题思路
    本题用递归的思路解决,定义递归函数void generate(vector< string>& res, string& str, int n, int len, int left, int right),其中 res 表示合法括号集,str 表示当前得到的括号字符串,n 表示输入的括号组数,len 表示 str 的长度,left 表示 str 中左括号的个数,right 表示 str 中右括号的个数。

    对每个初始为空的 str,可以不断地往其中加入左括号和右括号,直到左右括号被用完。需要注意的是,加入左右括号时必须满足以下规则:

    1. 如果左括号没有被用完,则可以继续添加左括号;
    2. 在添加右括号时,右括号的个数一定不能超过左括号(否则一定不合法)。

    该算法执行过程如下:

    1. 如果 len == 2*n ,表示得到合法括号,将其加入到 res 中,递归结束;
    2. 如果 left < n,则在 str 中加上左括号“(”,进行递归;
    3. 如果 right < left, 则在 str 中加上右括号“)”,进行递归。
  • 代码实现

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        string str = "";
        generate(res, str, n, 0, 0, 0);
        return res;
    }
    void generate(vector<string>& res, string& str, int n, int len, int left, int right){
        if (len == 2*n){
            res.push_back(str);
            return ;
        }
        if(left < n){
            str += "(";
            generate(res, str, n, len+1, left+1, right);
            str = str.substr(0, str.length()-1);
        }
        if(right < left){
            str += ")";
            generate(res, str, n, len+1, left, right+1);
            str = str.substr(0, str.length()-1);
        }
    }
};

Problem 26. Remove Duplicates from Sorted Array

  • 题目描述
    Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.

    Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

  • 解题思路
    本题较简单,原本是用 vector 的 erase 函数删除掉重复的值,但这样效率太慢。注意到题目中说到"It doesn’t matter what you leave beyond the returned length.",假设我们返回的无重复的长度为 len,则只要数组 nums 的前 len 个数字顺序正确且无重复即可。

    定义两个下标 pre 和 cur,cur 始终才 pre 的前面。当 nums[pre] == nums[cur] 时,cur 继续向下指。直到 nums[pre] != nums[cur],此时将 nums[cur] 赋值给 nums[++pre] 即可。

    扫描二维码关注公众号,回复: 5583078 查看本文章

    最后得到的无重复的长度为pre+1。

  • 代码实现

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int len = nums.size();
        if(len == 0)
            return 0;
        int pre = 0, cur = 1;
        for(; cur < len; ++cur){
            if(nums[pre] == nums[cur]) 
                continue;
            nums[++pre] = nums[cur];
        }
        return pre+1;
    }  
};

Problem 28. Implement strStr()

  • 题目描述
    Implement strStr().

    Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

  • 解题思路
    定义haystack的长度为len1,needle的长度为len2。遍历haystack,利用substr函数判断haystack.substr(i, len2)与needle相不相等即可。
    为了优化程序性能,在执行遍历的时候不需要将haystack完全遍历,当在以haystack[i]开始的字符串长度小于len2时,即可停止遍历。

  • 代码实现

class Solution {
public:
    int strStr(string haystack, string needle) {
        int len1 = haystack.length();
        int len2 = needle.length();
        int len = len1 - len2;
        for(int i = 0; i < len+1; ++i){
            if(needle == haystack.substr(i, len2)) return i;
        }
        return -1;
    }
};

Problem 29. Divide Two Integers

  • 题目描述
    Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.

    Return the quotient after dividing dividend by divisor.

    The integer division should truncate toward zero.

  • 解题思路
    既然不可以用乘、除等操作,那就得用减法来实现除法操作了。这里用了位运算,能极大提高计算效率。
    需要注意的地方有以下几个:

    1. 不可一开始就使用abs函数对传入的 dividend 和 divisor 进行绝对值化,因为-2147483648进行绝对值化后会overflow(int整型最大值为2147483647)。
    2. 对返回的结果要进行溢出判断,如果超出了2147483647,则赋值为2147483647。
  • 代码实现

class Solution {
public:
    int divide(int dividend, int divisor) {
        long long m = dividend;
        long long n = divisor;
        long long  res = 0;
        int sign = 1;

        if(m < 0){
            sign = -sign;
            m = -m;
        } 
        if(n < 0){
            sign = -sign;
            n = -n;
        }

        while(m >= n){
            long long t = n;
            for(int i = 0; t <= m; i++){
                m -= t;
                res += 1<<i;
                t = t<<1;
            }
        }

        if(sign < 0) 
            res =-res;
        res = res > INT_MAX ? INT_MAX : res;
        return int(res);
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_36348299/article/details/88530725