跳过正文

算法 2.3

·1384 字·3 分钟· loading ·
3ing
作者
3ing
Always looking forward to tomorrow.
目录

2.3
#

x 的平方根 (掌握程度: 低)
#

只记得是二分但是具体的一点都不太清楚,所以还是抄的题解

class Solution {
public:
    int mySqrt(int x) {
        int left = 0, right = x;
        int ans = 0;
        while (left <= right) {
            long long mid = (left + right) / 2;
            if (mid * mid <= x) {
                ans = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return ans;
    }
};

滑动窗口最大值 (掌握程度:低)
#

难度有点大的滑动窗口,因为这个用上了单调双向队列去解决的,不像其他的滑动窗口都是用双指针加哈希实现的,这个后续得花功夫去理解

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> ans;
        deque<int> q;
        for (int i = 0; i < n; i++) {
            while (!q.empty() && nums[q.back()] <= nums[i]) {
                q.pop_back();
            }
            q.push_back(i);
            int leftIdx = i - k + 1;
            if (q.front() < leftIdx) {
                q.pop_front();
            }
            if (leftIdx >= 0) {
                ans.push_back(nums[q.front()]);
            }
        }
        return ans;
    }
};

最长有效括号 (掌握程度: 中)
#

栈的处理我还是知道的,除了哨兵下标的存在和中间的答案的处理有点记不太清楚

class Solution {
public:
    int longestValidParentheses(string s) {
        int n = s.size();
        int ans = 0;
        stack<int> st;
        st.push(-1);
        for (int i = 0; i < n; i++) {
            if (s[i] == '(') {
                st.push(i);
            } else {
                st.pop();
                if (st.empty()) {
                    st.push(i);
                }
                ans = max(ans, i - st.top());
            }
        }
        return ans;
    }
};

下一个排列 (掌握程度:低)
#

一个对编码能力要求不高的题,但是很考验思维能力

  1. 为了满足最小变化,所以需要从最右边找到第一个非单调递减的数 如 123654 的3 所以 i = 2, nums[i] = 3
  2. 再从最右边开始找,找到一个最小但是比nums[i] 要大一点的数,123654 的 4 所以 j = 5, nums[j] = 4
  3. 交换之后 124653, 最后将交换的i的后面反转就变成最小的数了 124356
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int n = nums.size();
        int i = n - 2;
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        if (i >= 0) {
            int j = n - 1;
            while (j >= 0 && nums[i] >= nums[j]) {
                j--;
            }
            swap(nums[i], nums[j]);
        }
        reverse(nums.begin() + i + 1, nums.end());
    }
};

字符串转换整数 (atoi) (掌握程度:低)
#

一点都不会写的题,考我我就等死吧我去了

class Solution {
public:
    int myAtoi(string s) {
        int n = s.size();
        int ans = 0, i = 0, flag = 1;
        while(s[i] == ' ') i++;
        if (s[i] == '-') flag = -1;
        if (s[i] == '+' || s[i] == '-') i++;
        while (i < n && isdigit(s[i])) {
            int num = s[i] - '0';
            if (ans > INT_MAX  / 10 || (ans == INT_MAX / 10 && num > 7)) {
                return flag > 0 ? INT_MAX : INT_MIN;
            }
            ans = ans * 10 + num;
            i++;
        }
        return flag > 0 ? ans : -ans;
    }
};

两数相加 (掌握程度:高)
#

写了很多次的两数相加的链表题了

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* dummy = new ListNode(0);
        ListNode* cur = dummy;
        int carry = 0;
        while(l1 || l2 || carry > 0) {
            int sum = carry;
            if (l1) {
                sum += l1->val;
                l1 = l1->next;
            }
            if (l2) {
                sum += l2->val;
                l2 = l2->next;
            }
            ListNode* newNode = new ListNode(sum % 10);
            cur->next = newNode;
            cur = cur->next;
            carry = sum / 10;
        }
        return dummy->next;
    }
};

爬楼梯 (掌握程度: 高)
#

动态规划的简单题,动态规划那一套都懂,但是初始化和转移方程真的太难了

class Solution {
public:
    int climbStairs(int n) {
        vector<long long> dp(n + 2);
        dp[0] = dp[1] = 1;
        for (int i = 0; i < n; i++) {
            dp[i + 2] = dp[i + 1] + dp[i];
        }
        return dp[n];
    }
};

零钱兑换 (掌握程度: 中)
#

零钱兑换做了挺多次的了好像,但是还是记得不太清楚,边界处理和转移方程忘记了

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        int n = coins.size();
        vector<int> dp(amount + 1, amount + 1);
        dp[0] = 0;
        for (int i = 0; i < n; i++) {
            for (int j = coins[i]; j <= amount; j++) {
                dp[j] = min(dp[j], dp[j - coins[i]] + 1);
            }
        }
        if (dp[amount] > amount) return -1;
        return dp[amount];
    }
};

字符串相乘 (掌握程度:低)
#

一点都不会啊,完全没有头绪,看来只能背下来了

class Solution {
public:
    string multiply(string num1, string num2) {
        if (num1 == "0" || num2 == "0") return "0";
        int m = num1.size(), n = num2.size();
        vector<int> res(m + n, 0);
        // 从最低位开始相乘
        for (int i = m - 1; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                int mul = (num1[i] - '0') * (num2[j] - '0');
                int sum = mul + res[i + j + 1];
                res[i + j + 1] = sum % 10;   // 当前位
                res[i + j] += sum / 10;      // 进位
            }
        }
        // 跳过前导 0
        string ans;
        for (int i = 0; i < m + n; i++) {
            if (!(ans.empty() && res[i] == 0)) {
                ans += res[i] + '0';
            }
        }
        return ans;
    }
};

最小覆盖子串 (掌握程度:低)
#

知道怎么写但是具体实现记得不太清楚了,是双指针结合哈希表形成的滑动窗口

class Solution {
public:
    string minWindow(string s, string t) {
        int cnt[128]{};
        for(char c : t) cnt[c]++;
        int left = 0, right = 0;
        int need = t.size(), minLen = INT_MAX, start =0;
        while (right < s.size()) {
            if (cnt[s[right]] > 0) need--;
            cnt[s[right]]--;
            right++;
            while (need == 0) {
                if (right - left < minLen) {
                    minLen = right - left;
                    start = left;
                }
                cnt[s[left]]++;
                if (cnt[s[left]] > 0) need++;
                left++;
            }
        }
        return minLen == INT_MAX ? "" : s.substr(start, minLen);
    }
};

相关文章

算法 2.2

·730 字·2 分钟· loading
每日算法-2.2

算法 2.1

·871 字·2 分钟· loading
每日算法-2.1