LeetCode 3011.判断一个数组是否可以变为有序

注:这个题目有序的意思是"升序"

解法一:bubblesort O(nlogn)

核心思想:冒泡每次会将一个数归位到最后的位置上,所以我们如果碰到无法向右交换的数字,即可return false

cpp 复制代码
class Solution {
public:
    // 返回一个十进制数字对应的二进数中1的个数
    int getnum(int a){
        int res = 0;
        while(a){
            if(a & 1 == 1)  res ++;
            a >>= 1;
        }
        return res;
    }
    bool check(vector<int> & nums){
        int f1 = 1;
        for(int i = 0; i < nums.size() - 1; i ++){  // 升序有序(默认?)
            if(nums[i] > nums[i + 1]){
                f1 = 0;
                break;
            }
        }
        return f1; 
    }
    bool canSortArray(vector<int>& nums) {
        bool fg = true;
        int n = nums.size();
        unordered_map<int, int> mp;
        // 预处理出来所有的数字对应的二进制数字
        for(auto v : nums){
            int b = getnum(v);
            mp.insert({v, b});
            cout << v << " " << b << endl;
        }
        if(check(nums)) return fg;  // 原本是直接有序的
        else{
            for(int i = 0; i < n; i ++){
                for(int j = 0; j < n - i - 1; j ++){
                    // 每次都会将一个数字归位
                    if(nums[j] > nums[j + 1]){
                        if(mp[nums[j]] == mp[nums[j + 1]])
                            swap(nums[j], nums[j + 1]);
                        else    
                            return false;
                    }
                }
            }
        }
        return fg;
    }
};

解法二:模拟分组,指针单向扫描一遍O(N)

关键是发现相同元素进行分组,维护这个分组只需要指针i和premax两个信息, 然后切换至下一组时用curmax更新premax。要求本组的每一个元素都要大于前一个组的max值即可,否则需要跨组交换(不是一个组无法进行)

cpp 复制代码
class Solution {
public:
    int getnum(int a){
        int res = 0;
        while(a){
            if(a & 1)   res ++;
            a >>= 1;
        }
        return res;
    }

    bool canSortArray(vector<int>& nums) {
        int curmax = 0, premax = 0;
        // 要求当前组的每一个元素都要大于前一个组的最大值即可
        for(int i = 0; i < nums.size(); ){
            curmax = 0;     // 每次进入一个新的组,都要初始化为0
            int ones = getnum(nums[i]);
            while(i < nums.size() && getnum(nums[i]) == ones){ // 遍历本组
                if(nums[i] > curmax)   curmax = nums[i];    // 记录curmax用于初始化下一组的premax
                if(nums[i] < premax)    return false;       // 见第一行的要求
                i ++;
            }   
            premax = curmax;        // 进入下一组前设置好premax
        }
        return true;
    }
};
相关推荐
繁依Fanyi36 分钟前
使用 Spring Boot + Redis + Vue 实现动态路由加载页面
开发语言·vue.js·pytorch·spring boot·redis·python·算法
aloha_78942 分钟前
B站宋红康JAVA基础视频教程(chapter14数据结构与集合源码)
java·数据结构·spring boot·算法·spring cloud·mybatis
临沂堇1 小时前
CCF刷题计划——训练计划(反向拓扑排序)
数据结构·c++·算法·拓扑·ccf
铁匠匠匠1 小时前
【C总集篇】第八章 数组和指针
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
Unicorn建模1 小时前
2024“华为杯”中国研究生数学建模竞赛(E题)深度剖析|数学建模完整过程+详细思路+代码全解析
python·算法·数学建模
咕咕吖1 小时前
二叉树的层序遍历(c)
数据结构·算法
子非鱼9212 小时前
【JavaScript】LeetCode:41-45
开发语言·javascript·leetcode·链表·二叉树
“JB...One”2 小时前
openssl-AES-128-CTR加解密结构体
linux·数据结构·算法·ssl
爱数模的小云2 小时前
【华为杯】2024华为杯数模研赛D题 解题思路
算法·华为
好记性+烂笔头3 小时前
hot100-438. 找到字符串中所有字母异位词
算法