Leetcode【随便刷刷】

本文汇总了解决LeetCode上多种算法题目的方法,包括数组操作、字符串处理、链表操作等,涉及轮转数组、矩阵置零、统计能整除数字的位数等问题,并提供了详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

189. 轮转数组

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        k = k % nums.size();
        reverse(nums.begin(), nums.end());
        reverse(nums.begin(), nums.begin() + k);
        reverse(nums.begin() + k, nums.end());
    }
};

73. 矩阵置零

vector、map、set都可以用find函数,但是vector和后两个的用法不同

自己写的 

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        if(matrix.size() == 0) return;
        vector<int> seti;
        vector<int> setj;
        for(int i = 0; i < matrix.size(); i ++){
            for(int j = 0; j < matrix[0].size(); j ++){
                if(matrix[i][j] == 0){
                    seti.push_back(i);
                    setj.push_back(j);
                }
            }
        }
        for(int i = 0; i < matrix.size(); i ++){
            for(int j = 0; j < matrix[0].size(); j ++){
                if(find(seti.begin(), seti.end(), i) != seti.end()) matrix[i][j] = 0;
                if(find(setj.begin(), setj.end(), j) != setj.end()) matrix[i][j] = 0;  
            }
        }
        return;
    }
};

 560. 和为 K 的子数组

暴力法(通过但是超时)

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int res = 0;
        if(nums.size() == 0) return k == 0 ? 1 : 0;
        for(int i = 0; i < nums.size(); i++){
             int sum = 0;
            for(int j = i; j >= 0; j--){//这里正着遍历也行
                sum += nums[j];
                if(sum == k) res ++; 
            }
        }
        return res;

    }
};

实际上想让用前缀做

=====待补充=======

11. 盛最多水的容器

暴力(不能完全通过)

class Solution {
public:
    int maxArea(vector<int>& height) {
        int legth = 0;
        int h = 0;
        int res = 0;
        if(height.size() == 0) return 0;
        for(int i = 0; i < height.size(); i++){
            for(int j = i; j < height.size(); j++){
                legth = j - i;
                h = min(height[i], height[j]);
                res = res > legth * h ? res : legth * h; 
            }
        }
        return res;
    }
};

双指针法

我写的不太对:28/63

class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0;
        int right = height.size() - 1;
        int res = water(left, right, height[left], height[right]);
        while(left < right){
            if(water(left + 1, right, height[left + 1], height[right]) > water(left, right, height[left], height[right])) {
                res = water(left + 1, right, height[left + 1], height[right]);
                left += 1;
                continue;
                }
            if(water(left, right - 1, height[left], height[right - 1]) > water(left, right, height[left], height[right])) {
                res = water(left, right - 1, height[left], height[right - 1]);
                right -= 1;
                continue;
            }
            break;
        }
        return res;
    }
private:
    int water(int left, int right, int lefth, int righth){
        int h = min(lefth, righth);
        int l = right - left;
        //cout << right << left << endl;
        int res = h * l;
        return res;
    }
};

正确的在这里:height[left]和height[right]谁小移动谁!因为移动长板的话,就算下一个更长,因为另一边是短板,水量也只能减少!

class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0;
        int right = height.size() - 1;
        int res = 0;
        while(left < right){
            if(height[left] < height[right]) {
                res = res > height[left] * (right - left) ? res : height[left] * (right - left);
                left += 1;
            }else{
                res = res > height[right] * (right - left) ? res : height[right] * (right - left);
                right -=1;
            }
        }
        return res;
    }
};

2520. 统计能整除数字的位数

这种把每一数位提取出来的办法值得记一下

class Solution {
public:
    int countDigits(int num) {
        int t = num, res = 0;
        while (t) {
            if (num % (t % 10) == 0) {
                res += 1;
            }
            t /= 10;
        }
        return res;
    }
};

我的方法也许用时比较久

class Solution {
public:
    int countDigits(int num) {
        int val;
        int res = 0;
        string str = to_string(num);
        for(int i = 0; i < str.size(); i++){
            val = str[i] - '0';
            if(num % val == 0) res++;
        }
        return res;
    }
};

2558. 从数量最多的堆取走礼物

wow用到了priority_queue优先队列,维护最大堆!

class Solution {
public:
    long long pickGifts(vector<int>& gifts, int k) {
        priority_queue<int> q(gifts.begin(), gifts.end());
        while(k--){
            int x = q.top();
            q.pop();
            q.push(sqrt(x));
        }    
        long long res = 0;
        while(!q.empty()){
            res += q.top();
            q.pop();
        }
        return res;
    }
};

2103. 环和杆

class Solution {
public:
    int countPoints(string rings) {
        vector<vector<int>> vec(10,vector<int>(3));
        int res = 0;
        for(int i = 0; i < rings.size(); i = i + 2){
            if(rings[i] == 'R'){
                vec[rings[i+1]-'0'][0] = 1;
            }
            if(rings[i] == 'G'){
                vec[rings[i+1]-'0'][1] = 1;
            }
            if(rings[i] == 'B'){
                vec[rings[i+1]-'0'][2] = 1;
            }
        }
        int sum = 0;
        
        for(int i = 0; i < 10; i++){
            for(int j = 0; j < 3; j++){
                sum += vec[i][j];
            }
            if(sum == 3) res++;
            sum = 0;
        }
        return res;        
    }
};

318. 最大单词长度乘积

【需要回顾】

考虑位运算,位运算的优先级低所以注意加括号!!

注意数组的定义和初始化

max用的时候也许需要(int)(--)

class Solution {
public:
    int maxProduct(vector<string>& words) {
        int n = words.size();
        int res = 0;
        //int mask[n]={0};会报错,如果n是具体的数那ok
        int mask[n];
        memset(mask, 0 , sizeof(mask));
        for(int i = 0; i < n; i++){
            for(char c : words[i]){
                mask[i] |= 1 << (c - 'a');//取或
            }
            for(int j = 0; j < i; j++){
                if((mask[i] & mask[j]) == 0){//不加括号通不过
                    res = max(res, (int)(words[i].size()*words[j].size()));//不加int通不过
                    //if(res < words[i].size()*words[j].size()) res = words[i].size()*words[j].size();
                }
            }
        }
        return res;
    }
};

2586. 统计范围内的元音字符串数

class Solution {
public:
    int vowelStrings(vector<string>& words, int left, int right) {
        int res = 0;
        for(int i = left; i <= right; i++){
            string str = words[i];
            int size = words[i].size();
            if(str[0] == 'a' || str[0] == 'e' || str[0] == 'i' || str[0] == 'o' || str[0] == 'u')
                if(str[size-1] == 'a' || str[size-1] == 'e' || str[size-1] == 'i' || str[size-1] == 'o' || str[size-1] == 'u')
                    res++;
        }
        return res;
    }
};

【待做...】 

2609. 最长平衡子字符串

class Solution {
public:
    int findTheLongestBalancedSubstring(string s) {
       int count[2] = {0, 0};
       int res = 0;
       if(s.size() < 2) return 0;
       if(s[0] == '0') count[0]++; 
       for(int i = 1 ; i < s.size(); i++){
            if(s[i-1] == '1' && s[i] =='0'){
                int restemp = min(count[0],count[1]);
                res = max(res, restemp);
                count[0] = 1;
                count[1] = 0;
            }else if(s[i] == '0'){
                count[0]++;
            }else if(s[i] == '1'){
                count[1]++;
            }else{};
       }
        int restemp = min(count[0],count[1]);
        res = max(res, restemp);
       return res * 2;
    }
};

238. 除自身以外数组的乘积

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int product = 0;
        vector<int> res;
        vector<int> left(nums.size(), 1);
        vector<int> right(nums.size(), 1);
        left[0] = 1;//对于索引为0的元素,因为左侧没有元素,所以L(0)=1
        for(int i = 1; i < nums.size(); i++){
            left[i] = left[i - 1] * nums[i - 1];
        }
        right[nums.size() - 1] = 1;
        for(int i = nums.size() - 2; i >= 0; i--){
            right[i] = right[i + 1] * nums[i + 1];
        }
        for(int i = 0; i < nums.size(); i++){
            res.push_back(left[i] * right[i]);
        }
        return res;
    }
};

41. 缺失的第一个正数

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int res;
        int n = nums.size();
        for(int i = 0; i < n; i++){
            if(nums[i] <= 0) nums[i] = n + 1;
        }
        for(int i = 0; i < n; i++){
            int num = abs(nums[i]);
            if(num < n + 1) nums[num - 1] = - abs(nums[num - 1]);
        }
        for(int i = 0; i < n; i++){
            if(nums[i] > 0){
                res = i + 1;
                break;
            }
        }
        return res;
    }
};

739. 每日温度

暴力解法,无法通过所有案例

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> res(temperatures.size(), 0);
        for(int i = 0; i < temperatures.size(); i++){
            for(int j = i + 1; j < temperatures.size(); j++){
                if(temperatures[j] > temperatures[i]){
                    res[i] = j - i;
                    break;
                }
            }
        }
        return res;        
    }
};

【待补充..】

二维矩阵

240. 搜索二维矩阵 II

我的,每一行用二分法做,时间复杂度O(nlogn)这不是最简单的方法

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        for(int i = 0; i < matrix.size(); i++){
            if(searchArray(matrix[i], target) == true) return true;
        }
        return false;
    }
    bool searchArray(vector<int>& array, int target){
        int left = 0, right = array.size() - 1;
        while(left <= right){
            int middle = left + ((right - left)>>1);
            if(array[middle] < target){
                left = middle + 1;
            }else if(array[middle] > target){
                right = middle - 1;
            }else return true;
        }
        return false;
    }
};

一种很巧妙的方法,起点可以从左上角或者右下角开始,时间复杂度O(M+N)

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.size() == 0) return false;
        int i = 0, j = matrix[0].size() - 1;
        while(i < matrix.size() && j >= 0){
            if(matrix[i][j] > target){
                j--;
            }else if(matrix[i][j] < target){
                i++;
            }else return true;
        }
        return false;
    }
};

48. 旋转图像

. - 力扣(LeetCode)注意对称的组合可以构成旋转的效果

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        upDown(matrix, n);
        mainDiag(matrix, n);
    }
    void upDown(vector<vector<int>>& matrix, int n){
        for(int i = 0; i < n / 2; i++){
            for(int j = 0; j < n; j++){
                int temp = matrix[i][j];
                matrix[i][j] = matrix[n-1-i][j];
                matrix[n-1-i][j] = temp;
            }
        }
    }
    void mainDiag(vector<vector<int>>& matrix, int n){
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j < n; j++){
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
    }
};

字符串反转相关的题目

列一下:

链表反转相关题目:

反转链表_哔哩哔哩_bilibili

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* cur = head;
        ListNode* pre = NULL;
        while(cur != nullptr){
            ListNode* temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        return pre; 
    }
};
class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        ListNode* cur = dummy;
        left--;
        for(int i = 0; i < left; i++){
            cur = cur->next;
        }
        ListNode* pre = nullptr;
        ListNode* beginLeft = cur;
        cur = cur->next;
        ListNode* beginRight = cur;

        for(int i = 0; i < (right - left) && cur != nullptr; i++){
            ListNode* temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        beginLeft->next = pre;
        beginRight->next = cur;
        head = dummy->next;
        delete dummy;
        return head;

    }
};

记这个更好

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        ListNode* p0 = dummy;
        left--;
        for(int i = 0; i < left; i++){
            p0 = p0->next;
        }
        ListNode* pre = nullptr;
        ListNode* cur = p0->next;

        for(int i = 0; i < (right - left) && cur != nullptr; i++){
            ListNode* temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        p0->next->next = cur;
        p0->next = pre;
        
        head = dummy->next;
        delete dummy;
        return head;

    }
};

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        ListNode* p0 = head;
        int n = 0;
        while(p0 != nullptr){
            n++;
            p0 = p0->next;
        }
        p0 = dummy;
        while(n >= k){
            n -= k;
            ListNode* pre = nullptr;
            ListNode* cur = p0->next;
            for(int i = 0; i < k && cur != nullptr; i++){
                ListNode* temp = cur->next;
                cur->next = pre;
                pre = cur;
                cur = temp;
            }
            ListNode* nxt = p0->next;
            p0->next->next = cur;
            p0->next = pre;
            p0 = nxt;
        }

        
        head = dummy->next;
        delete dummy;
        return head;
    }
};

美团面试考了

可以用双端队列;或者结合翻转链表来做。

80. 删除有序数组中的重复项 II

我的

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int slow = 0, fast = 0;
        if(nums.size() < 3) return nums.size();
        while(fast < nums.size()){
            if(fast < nums.size() - 2){
                if(nums[fast] != nums[fast + 2]){
                    nums[slow] = nums[fast];
                    slow ++;
                }
            }else{
                    nums[slow] = nums[fast];
                    slow ++;
            }
            fast ++;
        }
        return slow;
    }
};

也可以

153. 寻找旋转排序数组中的最小值

用二分法,注意边界条件啊

class Solution {
public:
    int findMin(vector<int>& nums) {
        if(nums.size() == 1) return nums[0];
        int left = 0, right = nums.size() - 1;
        while(left < right){
            int middle = left + ((right - left) >> 1);
            if(nums[middle] > nums[right]){
                left = middle  + 1;
            }else if(nums[middle] <= nums[right]){
                right = middle;
            }
        }
        return nums[left];
    }
};

154. 寻找旋转排序数组中的最小值 II

在上一题的基础上只是多了nums[middle] == nums[right]条件下的判断,这种情况下只需要让right左移就好。

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0, right = nums.size() - 1;
        while(left < right){
            int middle = left + ((right - left) >> 1);
            if(nums[middle] > nums[right]){
                left = middle  + 1;
            }else if(nums[middle] < nums[right]){
                right = middle;
            }else right--;
        }
        return nums[left];
    }
};


====代码随想录中的附加题目====

1365. 有多少小于当前数字的数字

我的:

class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        vector<int> numsBackup(nums.begin(), nums.end());
        vector<int> res;
        sort(numsBackup.begin(), numsBackup.end());
        unordered_map<int,int> map;
        for(int i = 0; i < nums.size(); i++){
            if(map.find(numsBackup[i]) == map.end()) map[numsBackup[i]] = i;
            else map[numsBackup[i]] = min(map[numsBackup[i]], i);
        }
        for(int i = 0; i < nums.size(); i++){
            res.push_back(map[nums[i]]);
        }
        return res;
    }
};

改善1:第一个for循环用倒序遍历更好,这样可以找到相同元素的最小排序索引

        for(int i = nums.size() - 1; i >= 0; i--){
           // if(map.find(numsBackup[i]) == map.end()) map[numsBackup[i]] = i;
           // else 
           map[numsBackup[i]] = i;
        }

改善2:可以不用定义res向量,直接在numsBackup数组里覆盖。

改善3:题目中限制了0 <= nums[i] <= 100,所以可以用数组而不是map来存排序索引

改善后:

class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        vector<int> numsBackup(nums.begin(), nums.end());
        sort(numsBackup.begin(), numsBackup.end());
        int sortArray[101];
        for(int i = nums.size() - 1; i >= 0; i--){
           sortArray[numsBackup[i]] = i;//sortArray索引代表数字,值代表排序索引
        }
        for(int i = 0; i < nums.size(); i++){
            numsBackup[i] = sortArray[nums[i]];
        }
        return numsBackup;
    }
};

941. 有效的山脉数组

我的丑陋代码,标志位狂魔+面向案例编程..

class Solution {
public:
    bool validMountainArray(vector<int>& arr) {
        int flag = -1;
        if(arr.size() < 3) return false;
        for(int i = 1 ; i < arr.size(); i++){
            int diff = arr[i] - arr[i - 1];
            if(diff > 0 && flag == -1)  flag = 0;
            else if(diff < 0 && flag == 0) flag = 1;
            else if(diff == 0) return false;
            else if(diff < 0 && flag == -1) return false;
            else if(diff > 0 && flag == 1) return false;
            else{};
        }
        if(flag == 1) return true;
        else return false;
    }
};

 双指针法不容易出错误~

class Solution {
public:
    bool validMountainArray(vector<int>& arr) {
        int left = 0;
        int right = arr.size() - 1;
        while(left < arr.size() - 1){
            if(arr[left] < arr[left + 1]) left ++;
            else break;
        }
        while(right > 0){
            if(arr[right] < arr[right - 1]) right --;
            else break;
        }
        if(left == arr.size() - 1 ||left == 0) return false;
        if(right == arr.size() - 1 ||right == 0) return false;
        if(left == right) return true;
        else return false;
    }
};

1207. 独一无二的出现次数

和官方一样(^-^)V

class Solution {
public:
    bool uniqueOccurrences(vector<int>& arr) {
        unordered_map<int,int> map;
        unordered_set<int> set;
        for(int i = 0; i < arr.size(); i++){
            map[arr[i]]++;
        }
        for(auto count : map){
            set.insert(count.second);
        }
        if(set.size() == map.size()) return true;
        else return false;
    }
};

724. 寻找数组的中心下标

要注意:

1、题意:左边=右边,不包括本下标对应的值

2、对于负数,如果%2的话,奇数是返回-1的,而不是1

我的

class Solution {
public:
    int pivotIndex(vector<int>& nums) {
        int sum = 0;
        for(int n : nums) sum += n;
        int leftSum = 0;
        for(int i = 0; i < nums.size(); i++){
            leftSum += nums[i];
            if(abs(sum - nums[i]) % 2 == 1) continue;
            if(leftSum - nums[i] == (sum - nums[i]) / 2) return i;
        }
        return -1;
    }
};

34. 在排序数组中查找元素的第一个和最后一个位置

比代码随想录里面分别考虑左右边界要简单一点

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        if(nums.size() == 0) return {-1, -1};
        while(left <= right && left < nums.size() && right >= 0){
            //注意这条要先写,要不left就++,right就--了
            if(nums[left] == target && nums[right] == target) return {left, right};
            if(nums[left] < target) left++;
            if(nums[right] > target) right--;
        }
        return {-1,-1};
    }
};

922. 按奇偶排序数组 II

莫非我是天才?

class Solution {
public:
    vector<int> sortArrayByParityII(vector<int>& nums) {
        vector<int> res(nums.size());
        int k = 0, m = 0;
        for(int i = 0; i < nums.size(); i++){
            if(nums[i] % 2 == 0) {
                res[k * 2] = nums[i];
                k++;
            }
            if(nums[i] % 2 == 1) {
                res[m * 2 + 1] = nums[i];
                m++;
            }
        }
        return res;
    }
};

35. 搜索插入位置

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while(left <= right){
            int middle = left + ((right - left) >> 1);
            if(nums[middle] < target){
                left = middle + 1;
            }else if(nums[middle] > target){
                right = middle - 1;
            }else{
                return middle;
            }
        }
        return left;
    }
};

205. 同构字符串

class Solution {
public:
    bool isIsomorphic(string s, string t) { 
        unordered_map<char,char> maps2t;
        unordered_map<char,char> mapt2s;
        if(s.size() != t.size()) return false;
        int n = s.size();
        for(int i = 0; i < n; i++) {
            if(maps2t.find(s[i]) == maps2t.end()) maps2t[s[i]] = t[i];
            if(mapt2s.find(t[i]) == mapt2s.end()) mapt2s[t[i]] = s[i];
        }
        for(int i = 0; i < n; i++){
            if(maps2t[s[i]] != t[i]) return false;
            if(mapt2s[t[i]] != s[i]) return false;
        }
        return true;
    }
};

1002. 查找共用字符

我的

class Solution {
public:
    vector<string> commonChars(vector<string>& words) {
        vector<string> vec;
        int n = words.size();
        vector<vector<int>> hash(26, vector<int>(n, 0));
        unordered_map<char, int> map;
        for(int i = 0; i < n; i++){
            for(char c : words[i]){
                hash[c-'a'][i]++;
            }
        }
        for(int i = 0; i < 26; i++){
            map[i + 'a'] = INT32_MAX;
            for(int j = 0; j < n; j++){
                map[i + 'a'] = min(map[i + 'a'], hash[i][j]);
            }
        }
        for(auto m : map){
            for(int i = 0; i < m.second; i++){
                vec.push_back(string(1,m.first));
            }
        }
        return vec;
    }
};

844. 比较含退格的字符串

我用的栈,但是这种方法有点麻烦。字符串可以当栈用,而且两个字符串可以直接比较是否相同,比比较栈要方便。

我的(不好):

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        stack<char> s1, t1;
        s1 = transformStr(s);
        t1 = transformStr(t);
        return compareStr(s1, t1);
    }
    stack<char> transformStr(string str){
        stack<char> st;
        for(int i = 0; i < str.size(); i++){
            if(str[i] != '#') st.push(str[i]);
            else{
                if(!st.empty()) st.pop();
            }
        }
        return st;
    }
    bool compareStr(stack<char> st1, stack<char> st2){
        while(true){
            if(st1.empty() == true && st2.empty() == true) return true;
            else if(st1.empty() == false && st2.empty() == true) return false;
            else if(st1.empty() == true && st2.empty() == false) return false;
            else if(st1.top() != st2.top()) return false;
            else{
                st1.pop();
                st2.pop();
            } 
        }
    }
};

用字符串就行,好比较

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        return transformStr(s) == transformStr(t);
    }
    string transformStr(string str){
        string res;
        for(char c : str){
            if(c != '#') res.push_back(c);
            else if(c == '#' && !res.empty()) res.pop_back();
            else{}
        }
        return res;
    }
};

129. 求根节点到叶节点数字之和

我的

class Solution {
public:
    vector<vector<int>> pathSet;
    vector<int> path;
    int sumNumbers(TreeNode* root) {
        if(root == nullptr) return 0;
        path.push_back(root->val);
        iter(root);
        int res = calSum(pathSet);
        return res;
    }
    int calSum(vector<vector<int>> vec){
        int res = 0;
        int elem = 0;
        for(int i = 0; i < vec.size(); i ++){
            for(int j = 0; j < vec[i].size(); j++){
                elem += vec[i][j] * pow(10, (vec[i].size() - j - 1));
            }
            res += elem;
            elem = 0;
        }
        return res;
    }
    void iter(TreeNode* node){
        if(node->left == nullptr && node->right == nullptr){
            pathSet.push_back(path);
            return;
        }
        if(node->left){
            path.push_back(node->left->val);
            iter(node->left);
            path.pop_back();
        }
        if(node->right){
            path.push_back(node->right->val);
            iter(node->right);
            path.pop_back();
        } 
    }
};

204. 计数质数

暴力解法【一些例子会超时】

class Solution {
public:
    int countPrimes(int n) {
        int count = 0;
        if(n <= 2) return 0;
        for(int i = 2; i < n; i ++){
            if(isPrimes(i) == true) count++;
        }
        return count;
    }
    bool isPrimes(int a){
        for(int i = 2; i * i <= a; i++){
            if(a % i == 0) return false;
        }
        return true;
    }
};

2. 两数相加

这种方法,不能通过全部,因为链表的长度<100,没有合适的数据类型,longlong都不够了

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        vector<int> vec1, vec2;
        ListNode* cur = l1;
        while(cur != nullptr){
            vec1.push_back(cur->val);
            cur = cur->next;
        }
        cur = l2;
        while(cur != nullptr){
            vec2.push_back(cur->val);
            cur = cur->next;
        }
        long long num1 = vec2Num(vec1);
        long long num2 = vec2Num(vec2);
        long long sum = num1 + num2;
        vector<int> vec3;
        while(sum){
            vec3.push_back(sum % 10);
            sum /= 10;
        }
        ListNode* temp = new ListNode(0);
        ListNode* head = new ListNode(0);
        for(int i = 0; i < vec3.size(); i++){
            ListNode* node = new ListNode(vec3[i]);
            if(i != 0){
                temp->next = node;
            }else{
                head = node;
            }
            temp = node;
        }
        return head;

    }
    long long  vec2Num(vector<int>& vec){
        long long res = 0;
        for(int i = vec.size() - 1; i >= 0; i--){
            res += vec[i];
            res = res * 10;
        }
        return res / 10;
    }
};

进位法可以避免上面的问题

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {//l1 l2就是head..
        ListNode* myList = new ListNode(0);
        //myList->val = 3;
        ListNode* dummy = new ListNode(0);
        dummy->next = myList;
        ListNode* cur1 = l1;
        ListNode* cur2 = l2; 
        int plus = 0;
        int val;
        while(cur1 != NULL || cur2 != NULL){
            if(cur1 != NULL && cur2 != NULL) {
                val = cur1->val + cur2->val + plus; 
                if(myList!=nullptr) myList->next = new ListNode(val % 10);
                if(val >= 10) plus = val / 10;
                else plus = 0;
                cur1 = cur1->next;
                cur2 = cur2->next;
                myList = myList->next;
            }else if(cur1 != NULL && cur2 == NULL){
                val = cur1->val + plus;
                if(myList!=nullptr) myList->next = new ListNode(val % 10);
                if(val >= 10) plus = val / 10;
                else plus = 0;
                cur1 = cur1->next;
                myList = myList->next;
            }
            else{
                val = cur2->val + plus;
                if(myList!=nullptr) myList->next = new ListNode(val % 10);
                if(val >= 10) plus = val / 10;
                else plus = 0;
                cur2 = cur2->next;
                myList = myList->next;
            }
        }
        if(plus != 0) 
        {
            myList->next = new ListNode(plus);
        }
        return dummy->next->next;
    }
};

128. 最长连续序列

如果不限制空间复杂度n,这个题将会很简单。但是限制了,这样做

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> set;
        for(int i = 0; i < nums.size(); i++){
            set.insert(nums[i]);
        }
        int j = 0, res = 0;
        for(int s : set){
            if(set.find(s - 1) == set.end()){//如果是开头元素(找不到小一个的数)
                int curnum = s;
                int curres = 1;
                while(set.find(curnum + 1) != set.end()){
                    curres++;
                    curnum++;
                }
                res = max(res, curres);
            }
        }
        return res;
    }
};

只需要对每个开头的数进行循环,直到这个序列不再连续,因此复杂度是O(n)。 以题解中的序列举例: [100,4,200,1,3,4,2] 去重后的哈希序列为: [100,4,200,1,3,2]

按照上面逻辑进行判断:

元素100是开头,因为没有99,且以100开头的序列长度为1

元素4不是开头,因为有3存在,过,

元素200是开头,因为没有199,且以200开头的序列长度为1

元素1是开头,因为没有0,且以1开头的序列长度为4,因为依次累加,2,3,4都存在。

元素3不是开头,因为2存在,过,

元素2不是开头,因为1存在,过。

 42. 接雨水

双指针法

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0, left = 0, right = height.size() - 1, pre_max = 0, suf_max = 0;
        while (left < right) {
            pre_max = max(pre_max, height[left]);
            suf_max = max(suf_max, height[right]);
            ans += pre_max < suf_max ? pre_max - height[left++] : suf_max - height[right--];
        }
        return ans;
    }
};

在每一步迭代中,我们比较 pre_max 和 suf_max 的大小,然后决定是向左移动 left 指针还是向右移动 right 指针。这是因为我们总是希望先填满较低的一侧,因为这样可以确保后续接到的雨水不会溢出到已经填满的一侧。

 3. 无重复字符的最长子串

滑动窗口,注意收缩窗口的条件

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_set<char> set;
        int length = 0;
        int j = 0;
        for(int i = 0; i < s.size(); i++){
            while(set.find(s[i]) != set.end()){
                set.erase(s[j]);
                j++;
            }
            set.insert(s[i]);
            length = length>set.size()?length:set.size();
        }
        return length;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值