CodeTop

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

滑动窗口

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_set<char> uset;
        int n = s.size();
        int left = 0;
        int right = 0;
        int result = 0;
        int tmp;
        while(right < n)
        {
            if(uset.find(s[right]) == uset.end())
            {
                uset.insert(s[right]);
                right++;
            }else
            {
                uset.erase(s[left]);
                left++;
            }
            result = max(result,right-left);
        }
        return result;
    }
};

力扣

双指针法

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = nullptr;
        ListNode* cur = head;
        ListNode* tmp;
        while(cur)
        {
            tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};

215. 数组中的第K个最大元素

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int> pg;
        vector<int> vec(nums.size(),0);
        for(int i = 0; i < nums.size() ; i++)
        {
            pg.push(-nums[i]);
            if(pg.size() > k)
            {
                pg.pop();
            }
        }
        int ret = -pg.top();
        return ret;
    }
};

priority_queue<int> pg(优先队列)默认是大顶堆,所以在push的时候取反,就变成了小顶堆,然后就往里面添加,当当前堆大小大于k,就输出(就是把当前最小的输出出去)

25. K 个一组翻转链表

方法一,用栈,k个k个为一组,先入栈再出栈

/**
 * 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* reverseKGroup(ListNode* head, int k) {
        ListNode* cur = head;
        int count = 0;
        while(cur)
        {
            count++;
            cur = cur->next;
        }
        ListNode* result = new ListNode(0);
        result->next = head;
        ListNode* pre = result;
        ListNode* tmp;
        ListNode* mid;
        cur = head;
        stack<ListNode*> st;    
        for(int i = 0; i < count/k; i++)
        {
            int j = 0;
            while(j < k)
            {
                st.push(cur);
                cur = cur->next;
                j++;
            }
            mid = cur;
            j = 0;
            while(j < k)
            {
                tmp = st.top();
                st.pop();
                pre->next = tmp;
                pre = tmp;
                j++;
            }
            pre->next = cur;
        }
        return result->next;
    }
};

方法二,使用反转链表,找到k区间内的第一个和最后一个,然后翻转完,原来的头就是新的尾,原来的尾就是新的头,然后给连接起来就行

/**
 * 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:
    void reverse(ListNode* head,ListNode* tail){
        ListNode* cur = head;
        ListNode* tmp;
        ListNode* pre = nullptr;
        while(pre != tail)
        {
            tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* result = new ListNode(0);
        ListNode* pre = result;
        ListNode* tail;
        while(head)
        {
            tail = head;
            for(int i = 1; i < k; i++)
            {
                tail = tail->next;
                if(tail == nullptr)
                {
                    pre->next = head;
                    return result->next;
                }
            }
            ListNode* next = tail->next; // 需保存下一段头节点用于后续翻转
            reverse(head,tail);  // reverse 之后 newHead = tail, newTail = head
            pre->next = tail; // 将前一段与当前段连接,并移到下一段准备翻转
            pre = head;
            head = next;
        }
        return result->next;
    }
};

15. 三数之和

方法一(回溯算法):

超时了 阿西。。。

class Solution {
public:
vector<vector<int>> result;
    void backtracking(vector<int> cur,vector<int> nums,int startIndex,int sum)
    {
        if(cur.size() == 3 && sum == 0)
        {
            result.push_back(cur);
            return;
        }
        for(int i = startIndex; i < nums.size(); i++)
        {
            if(i > startIndex && nums[i] == nums[i-1])
            {
                continue;
            }else
            {
                sum += nums[i];
                cur.push_back(nums[i]);
                backtracking(cur,nums,i+1,sum);
                sum -= nums[i];
                cur.pop_back();
            }
        }
    }
    vector<vector<int>> threeSum(vector<int>& nums) {
        result.clear();
        vector<int> cur;
        sort(nums.begin(),nums.end());
        backtracking(cur,nums,0,0);
        return result;
    }
};

时间复杂度:O(n*2^n)

方法二(双指针)

class Solution {
public:
vector<vector<int>> result;
    vector<vector<int>> threeSum(vector<int>& nums) {
        result.clear();
        vector<int> cur;
        sort(nums.begin(),nums.end());
        for(int i = 0 ; i < nums.size(); i++)
        {
            if(nums[i] > 0)
                return result;
            if(i > 0&& nums[i] == nums[i-1])
            {
                continue;
            }else
            {
                int left = i+1;
                int right = nums.size()-1;
                while(right > left)
                {
                    if(nums[i] + nums[left] + nums[right] == 0)
                    {
                        result.push_back(vector<int>{nums[i],nums[left],nums[right]});
                        while(right > left && nums[right] == nums[right - 1])
                        {
                            right--;
                        }
                        while(right > left && nums[left] == nums[left +1])
                        {
                            left++;
                        }
                        left++;
                        right--;
                    }else if(nums[i] + nums[left] + nums[right] > 0)
                    {
                        right--;
                    }else if(nums[i] + nums[left] + nums[right] < 0)
                    {
                        left++;
                    }
                }
            }
        }
        return result;
    }
};

时间复杂度:O(N^2)

53. 最大子数组和

如果某一问题有很多重叠子问题,使用动态规划,每一个状态一定是由上一个状态推导出来的

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        vector<int> dp(nums.size(),0);
        dp[0] = nums[0];
        int result = dp[0];
        if(nums.size() == 1)
            return nums[0];
        for(int i = 1; i < nums.size(); i++)
        {
            dp[i] = max(dp[i-1]+nums[i],nums[i]);
            if(dp[i] > result)
                result = dp[i];
        }
        return result;
    }
};

​​​​​​912. 排序数组

冒泡排序:

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        for(int i = 0; i < nums.size(); i++)
        {
            bool flag = true;
            for(int j = nums.size()-1; j > 0; j--)
            {
                if(nums[j] < nums[j-1])
                {
                    swap(nums[j],nums[j-1]);
                    flag = false;
                }
            }
            if(flag)
                break;
        }
        return nums;
    }
};

插入排序

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        for(int i = 1; i < nums.size(); i++)
        {
            int tmp = nums[i];
            int j = i-1;
            while(j >= 0 && tmp < nums[j])
            {
                nums[j+1] = nums[j];
                j--;
            }
            nums[j+1] = tmp;
        }
        return nums;
    }
};

快速排序,要用到递归

class Solution {
public:
    int position(vector<int> &nums,int left,int right)
    {
        int pivot = nums[left];
        int i = left;
        int j = right;
        while(i < j)
        {
            while(i < j && nums[j] >= pivot)
                j--;
            nums[i] = nums[j];
            while(i < j && nums[i] <= pivot)
                i++;
            nums[j] = nums[i];
        }
        nums[i] = pivot;
        return i;
    }
    void QuickSort(vector<int> &nums,int left,int right)
    {
        if(left < right)
        {
            int pivot = position(nums,left,right);
            QuickSort(nums,left,pivot-1);
            QuickSort(nums,pivot+1,right);
        }
    }
    vector<int> sortArray(vector<int>& nums) {
        QuickSort(nums,0,nums.size()-1);
        return nums;
    }
};

21. 合并两个有序链表

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* result = new ListNode(0);
        ListNode* head = new ListNode(0);
        result = head;
        while(list2 && list1)
        {
            while(list2 && list1 && list1->val <= list2->val)
            {
                head->next = list1;
                head = head->next;
                list1 = list1->next;
            }
            while(list2 && list1 && list1->val > list2->val)
            {
                head->next = list2;
                head = head->next;
                list2 = list2->next;
            }
        }
        if(list2)
            head->next = list2;
        if(list1)
            head->next = list1;
        return result->next;
    }
};

1. 两数之和

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> unmap;
        for(int i = 0; i < nums.size(); i++)
        {
            unmap.insert(pair<int,int>(nums[i],i));
        }
        vector<int> result;
        for(int i = 0; i < nums.size(); i++)
        {
            int tmp = nums[i];
            int cur = target-tmp;
            if(unmap.find(cur) != unmap.end())
            {
                auto index = unmap.find(cur);
                if(index->second == i)
                    continue;
                else
                {
                    result.push_back(i);
                    result.push_back(index->second);
                    return result;
                }
            }
        }
        return result;
    }
};

unorder_map添加要用insert

102. 二叉树的层序遍历

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que;
        vector<vector<int>> result;
        if(root == nullptr)
            return result;
        que.push(root);
        int size;
        vector<int> eve;
        TreeNode* tmp;
        while(!que.empty())
        {
            size = que.size();
            eve.clear();
            while(size > 0)
            {
                tmp = que.front();
                que.pop();
                eve.push_back(tmp->val);
                size--;
                if(tmp->left)
                    que.push(tmp->left);
                if(tmp->right)
                    que.push(tmp->right);
            }
            result.push_back(eve);
        }
        return result;
    }
};

5. 最长回文子串

动态规划:

class Solution {
public:
    string longestPalindrome(string s) {
        vector<vector<bool>> dp(s.size(),vector<bool>(s.size(),false));
        int maxlength = 0;
        int left = 0;
        int right = 0;
        for(int i = s.size()-1; i >=0; i--)
        {
            for(int j = i; j < s.size(); j++)
            {
                if(s[i] == s[j])
                {
                    if(j-i <= 1)
                    {
                        dp[i][j] = true;
                    }else if(dp[i+1][j-1])
                    {
                        dp[i][j] = true;
                    }
                }
                if(dp[i][j] && j-i+1 > maxlength)
                {
                    maxlength = j - i + 1;
                    left = i;
                    right = j;
                }
            }
        }
        return s.substr(left,right-left+1);
    }
};

33. 搜索旋转排序数组

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

20. 有效的括号

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        int i = 0;
        while(s[i] != '\0')
        {
            if(s[i] == '(' || s[i] == '{' || s[i] == '[')
                st.push(s[i]);
            else
            {
                if(st.empty())
                    return false;
                if(s[i] == ')' && st.top() == '(')
                    st.pop();
                else if(s[i] == '}' && st.top() == '{')
                    st.pop();
                else if(s[i] == ']' && st.top() == '[')
                    st.pop();
                else
                    return false;
            }
            i++;
        }
        if(st.empty())
            return true;
        else 
            return false;
    }
};

121. 买卖股票的最佳时机

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(prices.size(),vector<int>(2,0));//0:买入 1:维持住
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        int result = 0;
        for(int i = 1; i < prices.size(); i++)
        {
            dp[i][0] = max(-prices[i],dp[i-1][0]);
            dp[i][1] = max(prices[i] + dp[i-1][0],dp[i-1][1]);
            if(dp[i][1] > result)
                result = dp[i][1];
        } 
        return result;
    }
};

分两种情况:买入和维持住,买入的话比较当前买入好还是前一天买入好,维持的话是比较卖掉好,还是保持之前的情况好

141. 环形链表

class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast && slow)
        {
            slow = slow->next;
            if(fast->next)
            {
                fast = fast->next->next;
            }else
                return false;
            if(fast == slow)
                return true;
        }
        return false;
    }
};

88. 合并两个有序数组

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = m+n-1;
        m = m-1;
        n = n-1;
        while(m >=0 && n >= 0)
        {
            if(nums1[m] < nums2[n])
            {
                nums1[i] = nums2[n];
                n--;
            }
            else
            {
                nums1[i] = nums1[m];
                m--;
            }
            i--;
        }
        while(n >= 0)
        {
            nums1[i] = nums2[n];
            i--;
            n--;
        }
        return;
    }
};

146. LRU 缓存

class LRUCache {
    // private Map<int,int> lruCache = new LinkedHashMap<>();
private: 
    int capacity;
    list<pair<int, int>> cache;   < @note pair[key]=value
    unordered_map<int, list<pair<int, int>>::iterator> lruCache;
public:
    LRUCache(int capacity) {
        this->capacity = capacity;
    }
    int get(int key) {
        if(lruCache.find(key) != lruCache.end())
        {
            pair<int,int> node = *lruCache[key];
            cache.erase(lruCache[key]);
            cache.push_front(node);
            lruCache[key] = cache.begin();
            return node.second;
        }else
            return -1;
    }
    void put(int key, int value) {
        auto newNode = std::make_pair(key, value);
        if(lruCache.find(key) != lruCache.end())
        {
            cache.erase(lruCache[key]);
        }else if(cache.size() == capacity)
        {
            lruCache.erase(cache.back().first);
            cache.pop_back();
        }
        cache.push_front(newNode);
        lruCache[key] = cache.begin();
        return;
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

C++的写法是unordered_map和list相结合啊啊啊

200. 岛屿数量

class Solution {
public:
    void DFS(vector<vector<char>>& grid,int i,int j,int row,int col)
    {
        // used[i][j] = 1;
        grid[i][j] = '0';
        if (i - 1 >= 0 && grid[i-1][j] == '1') DFS(grid, i - 1, j,row,col);
        if (i + 1 < row && grid[i+1][j] == '1') DFS(grid, i + 1, j,row,col);
        if (j - 1 >= 0 && grid[i][j-1] == '1') DFS(grid, i, j - 1,row,col);
        if (j + 1 < col && grid[i][j+1] == '1') DFS(grid, i, j + 1,row,col);
        return;
    }
    int numIslands(vector<vector<char>>& grid) {
        int row = grid.size();
        int col = grid.front().size();
        // vector<vector<int>> used(row,vector<int>(col,0));   //0:未使用 1:已使用
        int num = 0;
        for(int i = 0 ; i < row ; i++)
        {
            for(int j = 0; j < col; j++)
            {
                if(grid[i][j] == '0' )
                    continue;
                else
                {
                    DFS(grid,i,j,row,col);
                    num++;
                }
            }
        }
        return num;
    }
};

只要是有1就说明有岛,找到岛的边界,并把岛上的位置都设为0,防止重复找。

236. 二叉树的最近公共祖先

class Solution {
public:
    TreeNode* result;
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL || root == p || root == q)
        {
            return root;
        }
        TreeNode* left = lowestCommonAncestor(root->left,p,q);
        TreeNode* right = lowestCommonAncestor(root->right,p,q);
        if(left && right)
            return root;
        if(left)
            return left;
        if(right)
            return right;
        return NULL;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值