LeetCode刷题2

0612

LeetCode刷题2

    • 力扣刷题1
    • 力扣刷题2
      • 力扣83题:删除排序链表中的重复元素
      • 力扣82题:删除排序链表中的重复元素II
      • 力扣第8题:字符串转换整数 (atoi)
      • 力扣22题:括号生成
      • 力扣31题:下一个排列
        • 怎么用sort()对一个数组的局部进行排序?
      • 1143. 最长公共子序列
      • 力扣93题:复原IP地址
      • 力扣151题:颠倒字符串中的单词
      • 力扣105题:从前序与中序遍历序列构造二叉树
      • 力扣110题:平衡二叉树
      • 力扣129题:求根节点到叶节点数字之和
      • 力扣155题:最小栈
      • 力扣322题:零钱兑换
        • 动态规划
      • 力扣543题:二叉树的直径(力扣104题:求二叉树的深度)
      • 力扣43题:字符串相乘
      • 力扣112题:路径总和I & 113题:路径总和II
      • 力扣78题:
      • 画图,求总面积和重合面积
      • 解析指针数组中的字符串常量,把字符串中的内容按不同的分隔符分开
      • 把输入的内容以空格作为分隔符将其分成多个部分(c++实现split)
      • 剑指offer-04题

力扣刷题1

点这里

力扣刷题2

力扣83题:删除排序链表中的重复元素

版本1:(没用虚拟头结点)

class Solution {
   
public:
    ListNode* deleteDuplicates(ListNode* head) {
   
        //ListNode* preHead = new ListNode(0, head);
        ListNode* cur = head;
        while(cur && cur->next){
   //最少还剩两个节点
        	//两个结点值相等:就往后跳
            if(cur->val == cur->next->val){
   
                cur->next = cur->next->next;
            }
            else{
   //两个结点值不相等
                cur = cur->next;
            }          
        }
        return head;
    }
};

版本2:(用了虚拟头结点)

class Solution {
   
public:
    ListNode* deleteDuplicates(ListNode* head) {
   
        ListNode* preHead = new ListNode(0, head);
        ListNode* cur =  preHead;
        while(cur->next && cur->next->next){
   //链表最少还剩两个结点:
        	//两个结点值相等:从第二个开始删除
            if(cur->next->val == cur->next->next->val){
   
                cur->next->next = cur->next->next->next;
            }
            else{
   //两个结点值不相等:
                cur = cur->next;
            }
        }
        return preHead->next;
    }
};

力扣82题:删除排序链表中的重复元素II

class Solution {
   
public:
    ListNode* deleteDuplicates(ListNode* head) {
   
        ListNode* preHead = new ListNode(0, head);
        ListNode* cur = preHead;
        while(cur->next && cur->next->next){
   //链表最少还剩两个结点:
            //两个结点值相等:循环删掉相同的结点
            if(cur->next->val == cur->next->next->val){
   
                int tmp = cur->next->val;
                while(cur->next && cur->next->val == tmp){
   
                    cur->next = cur->next->next;
                }
            }
            //两个结点值不相等:
            else{
   
                cur = cur->next;
            }
        }
        return preHead->next;
    }
};

力扣第8题:字符串转换整数 (atoi)

剑指offer读书笔记4(面试题53-68)的第67题

class Solution {
   
public:
    int myAtoi(string s) {
   
        int n = s.size();
        if(n == 0) return 0;
        //空格:
        int i = 0;
        while(i < n && s[i] == ' '){
   
            ++i;
        } 
        //符号位
        char mark;
        if(s[i] == '+' || s[i] == '-') mark = s[i++];
        //数字
        long num = 0;
        while(i < n && s[i] >= '0' && s[i] <= '9'){
   
            num = num * 10 + (s[i] - '0');
            ++i;
            if(mark == '-'){
   
                if(-num < INT_MIN) 
                    return INT_MIN;
            }
            else{
   
                if(num > INT_MAX) 
                    return INT_MAX; 
            } 
        }
        //返回
        if(mark == '-') num = -num;
        return (int)num;
    }
};

力扣22题:括号生成

dfs+回溯

相当于是深度优先遍历一个满二叉树,把满足左括号个数lc和右括号个数rc同时等于n的情况筛选出来,存到vector res中。

代码1:(这个比较好理解)
(题解见括号生成 | 深度优先遍历 | 最简洁易懂的题解 【c++/java版】)

class Solution {
   
    vector<string> res;
    string path;
    int n;
public:
    vector<string> generateParenthesis(int n) {
   
        this->n = n;
        dfs(0, 0);
        return res;
    }
private:
    void dfs(int lc, int rc){
   
        if(lc == n && rc == n){
   //左右括号的个数都刚刚好够
            res.push_back(path);
            return;
        }
        if(lc < n){
   //左括号个数还没够
            path.push_back('(');
            dfs(lc + 1, rc);
            path.pop_back();
        }
        if(rc < n && rc < lc){
   //右括号个数还没够并且少于左括号的个数
            path.push_back(')');
            dfs(lc, rc + 1);
            path.pop_back();
        }
    }
};

代码2:
(题解见虽然不是最秀的,但至少能让你看得懂!下面的评论)

class Solution {
   
    vector<string> res;
    string path;
public:
    vector<string> generateParenthesis(int n) {
   
        //if(n == 0) return {};
        dfs(0, 0, n);
        return res;
    }
private:
    void dfs(int left, int right, int n){
   
        if(left > n || right > left) return;//right > n || left > right
        if(path.size() == n * 2){
    res.push_back(path); return; }
        
        path.push_back('(');
        dfs(left + 1, right, n);
        path.pop_back();

        path.push_back(')');
        dfs(left, right + 1, n);
        path.pop_back();
    }
};

力扣31题:下一个排列

题解见下一个排列算法详解:思路+推导+步骤,看不懂算我输!,代码见它下面的评论。

思路:
从后往前遍历,遇到一个数nums[i]比它前面的数nums[i - 1]大,
从这个数开始到数组结束的部分进行排序,
然后遍历这部分内容,找到第一个比nums[i - 1]大的数nums[j],把二者交换,然后return;
如果遍历完整个数组都没有遇到一个数nums[i]比它前面的数nums[i - 1]大的情况,就说明这个数组是降序的,对它进行排序,然后return;

代码:

class Solution {
   
public:
    void nextPermutation(vector<int>& nums) {
   
        int n = nums.size();
        for(int i = n - 1; i > 0; --i){
   
        	//找到一个比它前面一个数大的数:
            if(nums[i] > nums[i - 1]){
   
            	//迭代器:
                //auto it = nums.end();
                vector<int>::iterator it = nums.end();
                //从nums.end()开始倒着走n - i步:找到指向nums[i]的迭代器
                for(int k = 0; k < n - i; ++k) --it;
                //排序:
                sort(it, nums.end());
                //找到第一个比nums[i - 1]大的数:
                for(int j = 

你可能感兴趣的:(leetcode,链表,算法)