寒假刷题打卡第十九天 | 数组和矩阵

  1. 错误的集合
    最开始的想法是排序。但是
class Solution {
public:
    vector<int> findErrorNums(vector<int>& nums) {
        vector<int> count(nums.size());
        for(int& x:nums)
        {
            count[x-1]++;
        }
        int lose = -1;
        int repeat = -1;
        for(int i=0;i<count.size();i++)
        {
            if(count[i]==0)
                lose=i+1;
            if(count[i]==2)
                repeat=i+1;
        }
        return {repeat, lose};
        
    }
};
  1. 寻找重复数
    思路一:异或运算。先从1异或到n,将得到的值与数组中的每个值异或运算。结果不对,因为,数组中并非每个数都会出现一遍。
    思路二:用数组代替hashtable。
public:
    int findDuplicate(vector<int>& nums) {
        vector<int> v(nums.size()-1);
        for(int& x:nums)
        {
            if(v[x-1]==1)
                return x;
            v[x-1]++;
        }
        return 0;
    }
};

思路三:弗洛伊德环
3. 数组的度
用一个hashtabel记录没个数字出现的位置。

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        unordered_map<int, vector<int>> m;
        for(int i=0;i<nums.size();i++)
        {
            vector<int> v;
            m[nums[i]] = v;
        }
        for(int i=0;i<nums.size();i++)
        {
            m[nums[i]].push_back(i);
        }
        int maxFre = 0;
        int ans = nums.size();
        for(pair<int, vector<int>>x:m)  //为何不能写成for(pair<int, vector<int>>&x:m)
        {
            if(x.second.size()==maxFre)
            {
                ans = min(x.second[x.second.size()-1] - x.second[0] + 1,ans);
            }
            else if(x.second.size()>maxFre)
            {
                maxFre = x.second.size();
                ans = x.second[x.second.size()-1] - x.second[0] + 1;
            }
        }
        return ans;
    }
};

答案用hashtable记录没个数字出现的次数,以及第一次出现和最后一次出现的位置。
4. 托普利兹矩阵
先判断左下角,再判断右边部分

class Solution {
public:
    bool isToeplitzMatrix(vector<vector<int>>& matrix) {
        if(matrix.size()==0)
            return false;
        int rows=matrix.size();
        int cols=matrix[0].size();
        for(int i=rows-1;i>0;i--)
        {
            int val = matrix[i][0];
            int r=i,c=0;
            while(r<rows && c<cols)
            {
                if(matrix[r][c] != val)
                    return false;
                r++;
                c++;
            }
        }
        for(int i=0;i<cols;i++)
        {
            int val = matrix[0][i];
            int r=0,c=i;
            while(r<rows && c<cols)
            {
                if(matrix[r][c] != val)
                    return false;
                r++;
                c++;
            }
        }
        return true;
    }
};

评论区解法:判断上一行去掉最后一个元素和下一行去掉第一个元素后是否相等。

  1. 嵌套数组
    我的方法:暴力法。超时。利用set判断是否有重复。
class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        int maxLen = 0;
        for(int i=0;i<nums.size();i++)
        {
            unordered_set<int> s;
            int curLen;
            int curVal = nums[i];
            int curIndex = i;
            do{
                curLen = s.size();
                s.insert(nums[curIndex]);
                curIndex = nums[curIndex];
            }while(s.size()>curLen);  //do while ,新学的
            maxLen = max(maxLen, curLen);
        }
        return maxLen;
    }
};

其实不需要用集合来判断,因为对于第i轮循环,最终肯定会等于 i。
另外,如果某个元素之前已经被访问过,那么这轮循环得到的值肯定不是最大值,可以直接跳过。所以就有如下答案的解答。

class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        int maxLen = 0;
        vector<bool> visited(nums.size(), false);
        
        for(int i=0;i<nums.size();i++)
        {
            //cout << "a" << endl;
            //cout << visited[0] << endl;
            //cout << visited[i] << endl;
            if(!visited[i])
            {
                int curLen=0;
                int curIndex = i;
                do{
                    curLen++;
                    visited[curIndex] = true;
                    curIndex = nums[curIndex];
                }while(curIndex != i);
                maxLen = max(maxLen, curLen);
            }
        }
        return maxLen;
    }
};

另外,答案还提到,可以用O(1)的空间复杂度来做。但是需要改变原始数组。也就是,㘝访问过,就把原始数组的对应位置改为-1.

  1. 最多能完成排序的块
    当我们需要检查 [0, 1, …, n-1] 中前 k+1 个元素是不是 [0, 1, …, k] 的时候,只需要检查其中最大的数是不是 k 就可以了。
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) { //08:06 - 08:26
        int maxNum = 0, count = 0, ans=0;
        for(int i=0; i<arr.size();i++)
        {
            maxNum = max(arr[i], maxNum); 
            count++;
            if(count==maxNum+1)
                ans++;
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的体育馆管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本体育馆管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此体育馆管理系统利用当下成熟完善的SpringBoot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进程序开发。实现了用户在线选择试题并完成答题,在线查看考核数。管理员管理收货地址管理、购物车管理、场地管理、场地订单管理、字典管理、赛事管理、赛事收藏管理、赛事评价管理、赛事订单管理、商品管理、商品收藏管理、商品评价管理、商品订单管理、用户管理、管理员管理等功能。体育馆管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:体育馆管理系统;SpringBoot框架;Mysql;自动化
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值