当前位置:   article > 正文

力扣3011. 判断一个数组是否可以变为有序(c++实现)

力扣3011. 判断一个数组是否可以变为有序(c++实现)

方法一:插入排序

        这是自个做的时候写的, 排序最一开始使用的冒泡排序,结果发现冒泡排序无法保证相邻这一条件,就改为了插入排序。

  1. int cal_1(int a){ //判断该数有几个1
  2. int ans=0;
  3. while(a){
  4. a=a&(a-1); //a=a&(a-1)能够实现每次运算使最右侧的1变为0,这样1的个数便很好判断了
  5. ans++;
  6. }
  7. return ans;
  8. }
  9. class Solution {
  10. public:
  11. bool canSortArray(vector<int>& nums) {
  12. int len=nums.size();
  13. //利用插入排序的思想进行排序,只不过判断条件多了个1的个数是否相等的判断
  14. for(int i=1,j;i<len;i++){
  15. if(nums[i]<nums[i-1]&&cal_1(nums[i])==cal_1(nums[i-1])){
  16. int temp = nums[i];
  17. for(j=i-1;j>=0&&nums[j]>temp&&cal_1(nums[j])==cal_1(temp);j--){
  18. nums[j+1]=nums[j];
  19. }
  20. nums[j+1]=temp;
  21. }
  22. }
  23. for(int i=1;i<len;i++){ //判断数组是否有序
  24. if(nums[i]<nums[i-1]) return false;
  25. }
  26. return true;
  27. }
  28. };

以下方法是看了灵神的解析写的(灵神解析

方法二:分组循环

适用场景:按照题目要求,数组会被分割成若干组,每一组的判断/处理逻辑是相同的。

该题我们可以分析出,数组可以通过每个数二进制中1的个数进行分割。

  1. int cal_1(int a){
  2. int ans=0;
  3. while(a){
  4. a=a&(a-1);
  5. ans++;
  6. }
  7. return ans;
  8. }
  9. class Solution {
  10. public:
  11. bool canSortArray(vector<int>& nums) {
  12. int len=nums.size();
  13. for(int i=0;i<len;){ //外层循环,每次循环就是分的一段
  14. int start = i; //这一段的起始
  15. int n=cal_1(nums[i++]); //这一段起始的1的个数
  16. while(i<len && cal_1(nums[i])==n){ //内层循环,寻找这一段的结尾
  17. i++;
  18. }
  19. sort(nums.begin()+start,nums.begin()+i); //对这一段进行排序
  20. }
  21. return ranges::is_sorted(nums); //判断最后的数组是否有序
  22. }
  23. };

方法三:分组循环优化

其实每组没必要排序,经过分析可知,若这一组的值有小于上一组最大值的则不可能有序。 

  1. int cal_1(int a){
  2. int ans=0;
  3. while(a){
  4. a=a&(a-1);
  5. ans++;
  6. }
  7. return ans;
  8. }
  9. class Solution {
  10. public:
  11. bool canSortArray(vector<int>& nums) {
  12. int len = nums.size();
  13. int pre_max=0; //上一组的最大值
  14. for(int i=0;i<len;){
  15. int n = cal_1(nums[i]); //注意这里没有i++了,否则mx可能漏掉判断第一个数
  16. int mx=0; //这一组的最大值
  17. while(i<len && cal_1(nums[i])==n){
  18. if(nums[i]<pre_max) return false; //若这一组的数有小于上一组最大值的则false
  19. mx=max(mx,nums[i++]); //更新这一组的最大值
  20. }
  21. pre_max=mx; 将这一组的最大值赋给pre_max,供下一组使用
  22. }
  23. return true;
  24. }
  25. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/921093?site=
推荐阅读