Leetcode顺序刷题笔记(饱含注释版)

文章目录

  • 1、两数之和
  • 2、两数相加
  • 3、有效的括号
  • 4、合并两个有序链表
  • 5、括号生成
  • 6、移除元素
  • 7、搜索插入位置
  • 8、 字母异位词分组
  • 9、 将数组分成三个子数组的方案数
  • 10、不同路径


1、两数之和

Leetcode顺序刷题笔记(饱含注释版)_第1张图片
解法:

  1. 暴力法:双指针
  2. HashMap法:
    元素->缩影 拿元素作为key ,索引作为value。然后用target-key返回value;
class Solution
{
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> james;
        for (int i = 0;i<nums.size();++i)
        {
            auto it  = james.find(target-nums[i]);
            if (it != james.end())
            {
                return {it ->second,i};
            }
            james[nums[i]] = i ;
        }
        return {};
    }
};

2、两数相加

Leetcode顺序刷题笔记(饱含注释版)_第2张图片
解法:

  1. 迭代法(淳朴):
    从左往右相加,用一个新链表保存,中间可以加一个变量next用来做标志位呀。
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2)
    {
        ListNode* p = l1; // p作为l1的指针
        ListNode* q = l2;
        int len_l1 = 1;
        int len_l2 = 1;
        //获取l1的长度
        while(p->next != NULL)
        {
            ++ len_l1;
            p = p ->next;
        }
        //获取l2的长度
        while(q->next != NULL)
        {
            ++ len_l2;
            q = q ->next;
        }
        //比较长度,补0.
        if (len_l1 <= len_l2)
        {
            for(int i = 0 ; i <len_l2-len_l1 ;i++)
            {
                p -> next = new ListNode(0);
                p = p->next;
            }
        }
        else
        {
            for(int i = 0 ; i <= len_l1-len_l2 ;i++)
            {
                q -> next = new ListNode(0);
                q = q->next;
            }
        }
        //把指针还给l1和l2的首地址;
        p = l1;
        q = l2;
        bool record = false; //记录进位
        ListNode* l3 = new ListNode(-1); //存放结果的链表
        ListNode *w = l3;
        int i = 0;//记录相加结果
        while (p != NULL && q !=NULL)
        {
            i = record + p->val + q->val;
            w ->next = new ListNode(i%10);
            record = i >= 10?true:false;
            w = w->next;
            p = p->next;
            q = q->next;
        }
        if (record)
        {
            w->next = new ListNode(1);
            w = w->next;
        }
        return l3->next;



    }
};

3、有效的括号

为stack而生的解法

  1. 遍历一次,左括号全丢到里面
  2. 右括号,开始pop。

Leetcode顺序刷题笔记(饱含注释版)_第3张图片

class Solution 
{
public:
    bool isValid(string s) 
    {
        stack<char>S;
        for (char ch : s)
        {
            //如果当前栈为空,但是ch是右括号应该返回false
            if (S.empty() && ch == ')' || S.empty() && ch == ']' || S.empty() && ch == '}')
                return false;
            //如果ch是左括号,应该将其入栈,等待匹配
            if (ch == '(' || ch == '[' || ch == '{')
                S.push(ch);
            
            else
            {
                //如果输入的右括号和当前栈顶元素匹配,那么弹出栈顶元素
                if (S.top() == '(' && ch == ')' || S.top() == '[' && ch == ']' || S.top() == '{' && ch == '}')
                    S.pop();
                //当前栈顶元素与ch不匹配,直接返回false
                else
                    return false;
            }
        }
        //如果栈为空,返回true
        if (S.empty())
            return true;
        else
            return false;
    }
};

4、合并两个有序链表

Leetcode顺序刷题笔记(饱含注释版)_第4张图片

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* preHead = new ListNode(-1);

        ListNode* prev = preHead;
        while (l1 != nullptr && l2 != nullptr) {
            if (l1->val < l2->val) {
                prev->next = l1;
                l1 = l1->next;
            } else {
                prev->next = l2;
                l2 = l2->next;
            }
            prev = prev->next;
        }

        // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        prev->next = l1 == nullptr ? l2 : l1;

        return preHead->next;
    }
};

5、括号生成

Leetcode顺序刷题笔记(饱含注释版)_第5张图片

class Solution {
    shared_ptr <vector<string>> james[100] = {nullptr};//创建一个詹姆斯用作保存
    
public:
    shared_ptr <vector<string>> generate (int n)
    {
        //递归先加入判断中止符号
        if (james[n] != nullptr)
        {
            return james[n];
        }
        //排除没有东西的玩意儿
        if (n == 0) 
        {
            james[n] = shared_ptr <vector<string>>(new vector<string> {""});
        }
        else
        {
            auto result = shared_ptr<vector<string>>(new vector<string>);
            for (int i=0;i != n ;++i)
            {
                auto lefts = generate(i);
                auto rights = generate(n - i - 1);
                for (const string& left : *lefts)
                    for (const string& right : *rights)
                        result -> push_back("(" + left + ")" + right);
            }
            james[n] = result;
        }
        return james[n];
    }
    vector<string> generateParenthesis(int n)
    {
         return *generate(n);
        
    }
};

6、移除元素

Leetcode顺序刷题笔记(饱含注释版)_第6张图片
首先想法应该是双指针法,双指针是leetcode中比较简单的方法,一左一右美滋滋
Leetcode顺序刷题笔记(饱含注释版)_第7张图片

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n = nums.size();
        int left = 0;
        for (int right = 0; right < n; right++) {
            if (nums[right] != val) {
                nums[left] = nums[right];
                left++;
            }
        }
        return left;
    }
};

7、搜索插入位置

Leetcode顺序刷题笔记(饱含注释版)_第8张图片
Search Insert Position
返回的位置,就是插入的位置
常规法:遍历,遇到第一个比当前字数大的值,如果所有的值都比这个数小,就在最后插入On
二分法

  1. 两个指针,一头一尾
  2. 取 m=(首+尾)/2的值和当前值比较,如果小则将left移到m+1的地方,如果等于则返回当前值,这样每次都可以缩小一半的遍历条件
class Solution {
public:
    int searchInsert(vector<int>& nums, int target)
    {
        int n = nums.size();
        int left =0, right = n-1, ans = n;
        while(left <= right)
        {
            int mid = (right-left)/2+left;//取二分法中间值
            // if (target = nums[mid]) return mid;
            if (target <= nums[mid])
            {
                right = mid-1;
                ans = mid;
            }else
            {
                left = mid+1;
            }
        }
        return ans;   

    }
};

8、 字母异位词分组

在这里插入图片描述
像这种分组题,然后组内字母是相同的,一般使用:

  • 排序法
    对词进行排序
    java:hashmap
    python:字典
  • 哈希法
    找共同点,26个字母统计后,直接热码编码。返回hash表里面的值,数组是不是可以被哈希的,在python里面可以被hash的。tuple(元组可hash)

class Solution{
public:
vector james(vector& strs)
}

9、 将数组分成三个子数组的方案数

Leetcode顺序刷题笔记(饱含注释版)_第9张图片

10、不同路径

Leetcode顺序刷题笔记(饱含注释版)_第10张图片

class Solution {
public:
    int uniquePaths(int m, int n) 
    /*
    此题一看为动态规划题目;
    1、创建一个能记录状态的二维数组
    2、捕捉关系:机器人每次只能向下或者向右边走一步,说明新的位置只能为【i-1】或者【j-1】来得到
    3、确定初始值
    */
    {
        if(m == 0 && n==0)
        {
            return 0;
        }
        vector<vector<int>> dp (m,vector<int>(n));
        //如果当前的状态为j = 0,则它没有j-1的状态
        for (int i=0; i<m;i++)
        {
            dp[i][0] = 1;
        }
        for (int j=0; j<n;j++)
        {
            dp[0][j] = 1;
        }

        for (int i =1; i < m ;i++)
        {
            for(int j =1 ;j < n;j++)
            {
                dp[i][j] = dp[i-1][j]+dp[i][j-1];
            }
        }
        return dp[m-1][n-1];

    }
};

在这里插入图片描述

你可能感兴趣的:(Leetcode顺序刷题笔记(饱含注释版))