自学内容网 自学内容网

算法题目复习(0909-0917)

1. 连续子序列和

pdd的算法题,根本不记得怎么做

给一个数组,有正数和负数,算出连续子序列的和最大为多少

int maxSubArraySum(vector<int>& nums) {
    int maxSoFar = nums[0];
    int maxEndingHere = nums[0];

    for (size_t i = 1; i < nums.size(); ++i) {
        maxEndingHere = max(nums[i], maxEndingHere + nums[i]);
        maxSoFar = max(maxSoFar, maxEndingHere);
    }

    return maxSoFar;
}

int main() {
    std::vector<int> nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
    int maxSum = maxSubArraySum(nums);
    std::cout << "Maximum subarray sum is " << maxSum << std::endl;
    return 0;
}

Kadane's算法

太神了。。主要灵魂是:要么继续当前子数组,要么从当前位置开始一个新的数组(就是说如果过去的数加上i<i,就没必要用过去的数了)

2. 给一个字符串,只包含A和B两种字符,判断这个数组包含AB数量相等的连续子序列最长是多少,应该怎么做用c++

用一个哈希表记录前缀和

主要我做的时候想到了前缀和,但是不知道怎么找一个数组两个相等的数之差最大是多少

它的算法就是用哈希表存下来(idx,val),如果下一个val在哈希表中存在,就更新idx之差最大。这样On就能算了。

3 最长上升子序列

没想到这题用动态规划都得n平方,好难

思路就是dp[i] 是以i结尾的,前面任意选的子序列,dp[j]是以j结尾的子序列,要从j转移到i,就意味着nums[i]肯定大于nums[j], 那就找比i小的所有j里,dp[j]最大的进行转移,+1

    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> dp(n+1);
        dp[0] = 1;
        for(int i =1;i<n;i++){
            int maxj = 0;
            for(int j =0;j<i;j++){
                if(nums[j] < nums[i])
                    maxj = max(maxj, dp[j]);
            }
            dp[i] = maxj+1;
        }
        int res = 0;
        for(int i =0;i<n;i++){
            res = max(res, dp[i]);
        }
        return res;

4. 求质数

主要是求最小公约数,这个循环的话循环到sqrt(x)就行

或者先弄一个质数列表,这个列表得到的方式是:埃拉托斯特尼筛法

跟我想的差不多,用一个列表保存

还有!整除不要用/,用//

5. 搜索二维矩阵二

    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size(), n = matrix[0].size();
        int x = 0, y = n-1;
        while(x<m && y >= 0){
            if(matrix[x][y] == target){
                return true;
            }else if(matrix[x][y] > target){
                y --;
            }else{
                x++;
            }
        }
        return false;
    }

这题是z字形查找,就是从右上角的点开始查找,每次能排除一行或者一列

6. 图论的题

一直没搞清什么最短路那几个问题:

给一堆点,找到联通所有点的最短路

prim算法:找到n-1条边。每次选距离生成树最近的节点,将该点加入生成树,更新非生成树节点到生成树的距离。(初始化一个minDist数组,用来记录每个节点到生成树的最小距离)

初始化为每个点到第一个点的最小距离,然后迭代,它的重点在于选点,比较适合稠密图,复杂度是on平方

Krustral算法:是我自己想的那种并查集思路。对所有边按权值从大到小排列,判断选中的边的两个端点是否在一个并查集内,如果不在,就加入到一个。

djistra算法 

7. 随机链表的复制

就是给一个链表深拷贝为另一个链表,其中每个节点都有一个随机指针,指向任意一个节点

做法就是:定义两个old->new,new->old节点的映射map,第一次遍历创建新节点,并维护映射。第二次遍历根据老节点的random找到对应的新节点来设置新节点的random。

 Node* copyRandomList(Node* head) {
        unordered_map<Node*,Node*> mp;
        Node * head2 = new Node(0);
        Node * cur2 = head2;
        Node * cur = head;
        while(cur!=nullptr){
            cur2->next = new Node (cur->val);
            cur2 =cur2->next;
            mp[cur] = cur2;
            cur = cur->next;
        } 
        cur = head, cur2 = head2->next;
        while(cur!=nullptr){
            cur2->random = mp[cur->random];
            cur = cur->next;
            cur2 = cur2->next;
        }
        return head2->next;
    }


原文地址:https://blog.csdn.net/weixin_44858585/article/details/142049294

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!