Leetcode 题库解答

1. 两数之和

解法1:暴力解法

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int size = nums.size();
        vector<int> result;
        for (int i = 0; i < size ; i++) {
            for (int j = i + 1; j < size ; j++){
                if (nums[i] + nums[j] == target) {
                    result.push_back(i);
                    result.push_back(j);
                    return result;
                }
            }
        }
        return result;
    }
};

解法2:unordered_map

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int n = nums.size();
        unordered_map<int,int> map;
        for (int i = 0;i < n;i++){
            if (map.count(nums[i]) == 0) map[nums[i]] = i;
            if (map.count(target-nums[i]) != 0 && map[target-nums[i]] != i) 
                return{map[target-nums[i]],i};
        }
        return {};
    }
};
2. 两数相加

(暴力解法:倒转+倒转)

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        int num1 = 0, num2 = 0;
        ListNode* temp = l1;
        int idx = 0;
        while(temp) {
            num1 += (temp->val) * pow (10, idx);
            idx += 1;
            temp = temp->next;
        }
        temp = l2;
        idx = 0;
        while(temp) {
            num2 += (temp->val) * pow (10, idx);
            idx += 1;
            temp = temp->next;
        }
        int result = num1 + num2;
        ListNode *ans = new ListNode(result % 10);
        ListNode* ptr = ans;
        result /=10;
        while(result){
            ans->next = new ListNode(result % 10);
            ans = ans->next;
            result /=10;
        }
        return ptr;
    }
};

逐位相加:

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        int carry = 0;
        ListNode* result = nullptr;
        ListNode* ptr;
        while(l1 || l2) {
            int num1 = l1 ? l1->val : 0;
            int num2 = l2 ? l2->val : 0;
            int sum = num1 + num2 + carry;
            if (!result) {
                ptr = result = new ListNode(sum % 10);
            }
            else {
                result->next = new ListNode(sum % 10);
                result = result->next;
            }
            carry = sum / 10;
            if (l1) l1 = l1->next;
            if (l2) l2 = l2->next;
        }
        if (carry > 0) {
            result->next = new ListNode(carry);
        }
        return ptr;
    }
};
3. 无重复字符的最长子串

解法1(set):滑动窗口

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int start = 0, end = 0;
        int max_size = 0;
        set<char> group; 
        while (start < s.length()) {
            while (end < s.length() && group.count(s[end]) == 0) {
                group.insert(s[end]);
                end += 1;
            }
            max_size = std::max(max_size, int(group.size()));
            while (s[start] != s[end]) {
                group.erase(s[start]);
                start += 1;
            }   
            group.erase(s[start]);
            start += 1;
        }
        return max_size;
    }
};

解法2(unordered_map):滑动窗口

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> charIndexMap;
        int maxLength = 0;
        int start = 0;

        for (int end = 0; end < s.length(); ++end) {
            char currentChar = s[end];
            if (charIndexMap.find(currentChar) != charIndexMap.end()) {
                start = max(start, charIndexMap[currentChar] + 1);
            }
            charIndexMap[currentChar] = end;
            maxLength = max(maxLength, end - start + 1);
        }
        return maxLength;
    }
};

解法3(int flag[128]):

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.size();
        if (n == 0)
            return 0;
        int ans = 0;
        int flag[128] = { 0 };
        int left = 0, right = 0;
        int count = 0;
        while (right < n) {
            if (++flag[s[right]] == 2)
                count++;
            right++;
            while (count > 0) {
                if (--flag[s[left]] == 1)
                    count--;
                left++;
            }
            ans = max(ans, right - left);
        }
        return ans;
    }
};
5. 最长回文字串
class Solution {
public:
    string longestPalindrome(string s) {
        int length = 0;
        int start = 0;
        int flag = 0;
        for(int i = 0; i < s.length() - 1; i++){
            //奇数情况
            int count = 0;
            while( i - count >= 0 && i + count < s.length() && s[i - count] == s[i + count]){
                count++;
            }
            count--;
            if(count > length){
                start = i - count;
                length = count;
                flag = 0;
            }
            //偶数情况
            if(i + 1 < s.length() && s[i] == s[i + 1]){
                count = 0;
                while (i - count >= 0 && i + count + 1 < s.length() && s[i - count] == s[i + 1 + count])
                    count ++;
                count --;
                if(2 * count + 2 > 2 * length + 1){
                    flag = 1;
                    start = i - count;
                    length = count;
                }
            }
            
        }
        if (flag) return s.substr(start, 2 * length + 2);
        return s.substr(start, 2 * length + 1);
    }
};
6. Z字形变换
class Solution {
public:
    string convert(string s, int numRows) {
        vector<vector<string>> container;
        int flag = 0;
        int line = 0;
        for(int i = 0; i < s.length(); i++) {
            container[line].push_back(s[i]);
            if(!flag) line ++;
            else line --;
            if( line == numRows || line == 0 ) flag = (flag + 1) % 2;
        }
        int idx = 0;
        while(idx < container.size()){
            vector<string> temp = container[idx];
            int index = 0;
            while(index < temp.size()){
                cout << temp[index];
            }
            idx++;
        }
    }
};
20. 有效的括号
class Solution {
public:
    bool isValid(string s) {
        stack<char> ops;
        for (int i = 0;i < s.length(); i++) {
            if (s[i] == '(' || s[i] == '[' || s[i] == '{') ops.push(s[i]);
            else {
                if (ops.empty()) return false;
                char op = ops.top();
                ops.pop();
                if (s[i] == ')' && op != '(') return false;
                if (s[i] == ']' && op != '[') return false;
                if (s[i] == '}' && op != '{') return false;
            }
        }
        if (!ops.empty()) return false;
        return true;
    }
};
26. 删除有序数组中的重复项
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        set<int> once;
        for(int i = 0; i < nums.size(); i++) {
            if(once.find(nums[i]) != once.end()) {
                nums.erase(nums.begin() + i);
                i--;
            }
            else {
                once.insert(nums[i]);
            }
        }
        return nums.size();
    }
};
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) {
            return 0;
        }
        int fast = 1, slow = 1;
        while (fast < n) {
            if (nums[fast] != nums[fast - 1]) {
                nums[slow] = nums[fast];
                ++slow;
            }
            ++fast;
        }
        return slow;
    }
};
27. 移除元素
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] != val) {
                nums[k] = nums[i];
                k++;
            }
        }
        return k;
    }
};
94. 二叉树的中序遍历

解法1: 递归

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        if (!root) return result;
        vector<int> left = inorderTraversal(root->left);
        result.insert(result.end(), left.begin(), left.end());
        result.push_back(root->val);
        vector<int> right = inorderTraversal(root->right);
        result.insert(result.end(), right.begin(), right.end());
        return result;
    }
};

 解法2:迭代

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> stk;
        while (root != nullptr || !stk.empty()) {
            while (root != nullptr) {
                stk.push(root);
                root = root->left;
            }
            root = stk.top();
            stk.pop();
            res.push_back(root->val);
            root = root->right;
        }
        return res;
    }
};

125. 验证回文串
class Solution {
public:
    bool isPalindrome(string s) {
        int start = 0, end = s.length() - 1;
        while (start < end) {
            while (start < end && !isalpha(s[start]) && !isdigit(s[start])) start += 1;
            while (start < end && !isalpha(s[end]) && !isdigit(s[end])) end -= 1;
            if (tolower(s[start]) != tolower(s[end])) {
                return false;
            }
            start += 1 ;
            end -= 1;
        }
        return true;
    }
};
485. 最大连续1的个数
class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        int max = 0;
        int temp = 0;
        for(int i = 0; i < nums.size(); i++) {
            if(nums[i] == 1) {
                temp++;
            }
            else {
                max = (temp > max) ? temp : max;
                temp = 0;
            }
        }
        max = (temp > max) ? temp : max;
        return max;
    }
};
704. 二分查找
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int start = 0, end = nums.size() - 1;
        int pivot;
        while(start <= end) {
            pivot = (start + end)/2;
            if(nums[pivot] == target) return pivot;
            else if(nums[pivot] < target) start = pivot + 1;
            else end = pivot - 1;
        }
        return -1;
    }
};
1935. 可以输入的最大单词数

解法一:标记数组

class Solution {
public:
    int canBeTypedWords(string text, string brokenLetters) {
        int sum = 0;
        int mask[26] = {0};
        for (int i = 0; i < brokenLetters.length(); i++) {
            mask[brokenLetters[i]-'a'] = 1;
        }
        for (int index = 0; index < text.length(); index++) {
            bool flag = true;
            while(index < text.length() && text[index]!=' '){
                if (!flag) {
                    index++;
                    continue;
                }
                if (mask[text[index]-'a'] == 1){
                    flag = false;
                }
                index++;
            }
            if(flag) sum += 1;
        }
        return sum;
    }
};

解法二:哈希数组

class Solution {
public:
    int canBeTypedWords(string text, string brokenLetters) {
        unordered_set<char> broken;
        for (char ch: brokenLetters){
            broken.insert(ch);
        }
        int res = 0;
        bool flag = true;
        for (char ch: text){
            if (ch == ' '){
                if (flag){
                    ++res;
                }
                flag = true;
            }
            else if (broken.count(ch)){
                flag = false;
            }
        }
        if (flag){
            ++res;
        }
        return res;
    }
};

/*
作者:力扣官方题解
链接:https://leetcode.cn/problems/maximum-number-of-words-you-can-type/solutions/883398/ke-yi-shu-ru-de-zui-da-dan-ci-shu-by-lee-5dpc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/
2197. 替换数组中的非互质数

解法一:暴力查找

class Solution {
public:
    vector<int> replaceNonCoprimes(vector<int>& nums) {
        for(int i = 0; i < nums.size() - 1; i++) {
            int j = gcd(nums[i],nums[i + 1]);
            if (j>1) {
                nums[i] = nums[i] / j * nums[i + 1];
                nums.erase(nums.begin() + i + 1);
                if (i >= 1) {
                    i -= 2;
                }
                else i = -1;
            }

        }
        return nums;
    }
};

解法二:局部存储,栈

class Solution {
public:
    vector<int> replaceNonCoprimes(vector<int>& nums) {
        vector<int> ans;
        for (int num: nums) {
            while (!ans.empty()) {
                int g = gcd(ans.back(), num);
                if (g > 1) {
                    num = ans.back() / g * num;
                    ans.pop_back();
                }
                else {
                    break;
                }
            }
            ans.push_back(num);
        }
        return ans;
    }
};

其中gcd实现算法为辗转相除法:

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}
3408. 设计任务管理器
class TaskManager {
public:
    TaskManager(vector<vector<int>>& tasks) {
        for (int i = 0; i < tasks.size(); i++) {
            order.emplace(tasks[i][2],tasks[i][1]);
            myTasks[tasks[i][1]] = {tasks[i][2], tasks[i][0]};
        }
    }
    
    void add(int userId, int taskId, int priority) {
        myTasks[taskId] = {priority, userId};
        order.emplace(priority, taskId);
    }
    
    void edit(int taskId, int newPriority) {
        if (myTasks.find(taskId)!= myTasks.end()){
            myTasks[taskId].first = newPriority;
            order.emplace(newPriority,taskId);
        }
    }
    
    void rmv(int taskId) {
        myTasks.erase(taskId);
    }
    
    int execTop() {
        while (!order.empty()) {
            auto [priority, taskId] = order.top();
            auto it = myTasks.find(taskId);
            if (it == myTasks.end() || it->second.first != priority) {
                order.pop();
            } else {
                int userId = it->second.second;
                myTasks.erase(it);
                order.pop();
                return userId;
            }
        }
        return -1;
    }
private:
    priority_queue<pair<int,int>> order;
    unordered_map<int, pair<int,int>> myTasks;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值