LeetCode数组与矩阵专题(未完成)

1. 把数组中的 0 移到末尾

283. Move Zeroes (Easy)

Leetcode / 力扣

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
public void moveZeroes(int[] nums) {
    int idx = 0;
    for (int num : nums) {
        if (num != 0) {
            nums[idx++] = num;
        }
    }
    while (idx < nums.length) {//不够长度的话后面补0
        nums[idx++] = 0;
    }
}

这么简单的答题方法我初看居然还没看懂。。。大脑像鹅毛一样空白。。。

iter快捷键对list容器做了那么多次foreach遍历,居然换成数组就愣了。。。

foreach语句是java5的新特征之一,在遍历数组、集合方面,foreach为开发人员提供了极大的方便。
foreach语句是for语句的特殊简化版本,但是foreach语句并不能完全取代for语句,然而,任何的foreach语句都可以改写为for语句版本。
foreach并不是一个关键字,习惯上将这种特殊的for语句格式称之为“foreach”语句。从英文字面意思理解foreach也就是“for 每一个”的意思。实际上也就是这个意思
foreach的语句格式:
for(元素类型t 元素变量x : 遍历对象obj){
     引用了x的java语句;
}

这题我是用嵌套交换.......完全没想到直接跳过0后面补0就是......

 遇到一个问题就是0和0相连,在第二层嵌套j循环里的while循环中交换以后,由于current还是0,跳不出while循环。用continue还是继续while循环,用break直接跳出j嵌套到i里去了,而我只是想让j往后退一位再来同current交换。。。。这里没有解决导致0和0无限交换超时错误

 最后是拆掉j的for循环,把初始条件放i的for循环里,把控制条件放到while循环的条件里,把j++放到while循环末尾。(IDEA里debug了半天,cotinue,break,return应该弄清楚了)

public class test {
    public static void main(String[] args) {
        int s[] = {1,0,3,0,4};//关于数组的的初始化我也卡住了。。。int[] ss = new int[10];这样只是赋给一个数组空间
        moveZeroes(s);
        System.out.println(Arrays.toString(s));

    }
    //283
    static void moveZeroes(int[] nums) {
        if(nums==null) {
            return;
        }
        int length = nums.length;
//        int[] s = new int[length];
//        s = (int[]) nums.clone(); 不能用这个,一是题目不允许,二是这样根本就不对

        for(int i = 0;i<length;i++){
            int j =i+1;
                while(nums[i]==0&&j<length){
                    int temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                    j=j+1;
                }
            }
        }
    }

这个交换的思想可以再优化:

一次遍历
这里参考了快速排序的思想,快速排序首先要确定一个待分割的元素做中间点x,然后把所有小于等于x的元素放到x的左边,大于x的元素放到其右边
这里我们可以用0当做这个中间点,把不等于0(注意题目没说不能有负数)的放到中间点的左边,等于0的放到其右边
这的中间点就是0本身,所以实现起来比快速排序简单很多,我们使用两个指针i和j,只要nums[i]!=0,我们就交换nums[i]和nums[j]
请对照动态图来理解:(点链接)

作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/move-zeroes/solution/dong-hua-yan-shi-283yi-dong-ling-by-wang_ni_ma/

class Solution {
    public void moveZeroes(int[] nums) {
        if(nums==null) {
            return;
        }
        //两个指针i和j
        int j = 0;
        for(int i=0;i<nums.length;i++) {
            //当前元素!=0,就把其交换到左边j中,然后j进1,等于0的交换到右边i中,然后i进1
            if(nums[i]!=0) {
                int tmp = nums[i];
                nums[i] = nums[j];
                nums[j++] = tmp;
            }
        }
    }
}

(ps:nums[j++]=nums[j],只是j自增了

这里i是遇到不等于0才跟发生交换后,若是都是不等于0,则i和j都是自增1保持相等自身与自身交换。

若i遇到等于0 的会跳过i也会自增。不理解的话看一次遍历的动图

所以i是快指针,j是慢指针??

2. 改变矩阵维度

566. Reshape the Matrix (Easy)

Leetcode / 力扣

---------------------------------------------------------------------------------没看懂。。。

关于数组的定义与使用:

https://blog.csdn.net/mrbacker/article/details/81638331

https://www.sxt.cn/Java_jQuery_in_action/seven-array-characteristic.html

多维数组重点在维,每一维的列数可以不一样。int[][] a = new int[3][];

 int s[] = {1,0,3,0,4};

矩阵好像不是。。不过矩阵好像就是特殊的多维数组,特殊在于每一维的列数都相等。int[][] aa = new int[3][2];

int data[][] = new int[][] {{1, 2}, {3,4}};

---------------------------------------------------------------------------------------

一个m行n列的矩阵的挨个儿元素的遍历(不用嵌套循环,i和j是嵌套给res遍历用了,所有nums不能再用了):

int index从0到m*n-1:   nums[index / n][index % n];index++;

这是不是只能记住了??。。。index/n分行(停留久一些,且不同值),index%n才能分列(每一个都能后移,且能循环)

public int[][] matrixReshape(int[][] nums, int r, int c) {
    int m = nums.length, n = nums[0].length;//m是行数,n是列数
    if (m * n != r * c) {//要求元素总数相等
        return nums;
    }
    int[][] reshapedNums = new int[r][c];
    int index = 0;
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            reshapedNums[i][j] = nums[index / n][index % n];//遍历每一个 挨个儿赋值给重塑的矩阵形状
            index++;
        }
    }
    return reshapedNums;
}

3. 找出数组中最长的连续 1

485. Max Consecutive Ones (Easy)

Leetcode / 力扣

给定一个二进制数组, 计算其中最大连续1的个数。

我根据本章第1题的思路答出来了,但是我的解题方法太流氓了。。。我把未通过的头和尾设为特殊情况了

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        if(nums==null) {
            return 0;
        }
         int s[] = {1};
         if(Arrays.equals(nums, s)){//头部的流氓答法(只有1个1) 这我还查了半天
             return 1;
         }

        int length = nums.length;
        int j=0,p = 0;
        for(int i =0;i<length;i++){
            if(nums[i]!=1){
                if(p<i-j)
               { p =i-j;}
                j=i+1;
            }
            if(i==length-1&&nums[i]==1){//尾部也是
                if(p<i-j+1){
                    p=i-j+1;
                }
            }
        }
        return p;
    }
}

我的思路好像就总是这样。。。不知道为啥改不了

评论区的暴力法是count++计数

大神解法,用Math.max()存住大的那个遍历一下比一下,反正存住的总是大的

public int findMaxConsecutiveOnes(int[] nums) {
    int max = 0, cur = 0;
    for (int x : nums) {
        cur = x == 0 ? 0 : cur + 1;
        max = Math.max(max, cur);
    }
    return max;
}

4. 有序矩阵查找

240. Search a 2D Matrix II (Medium)

Leetcode / 力扣

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:

每行的元素从左到右升序排列。
每列的元素从上到下升序排列。

我第一想法遍历矩阵??两个for循环或者之前学的nums[index/n][index%n].......

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
         for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[0].length; j++) {
            if(target == matrix[i][j])
            return true;
        }
    }
    return false;
    }
}

解答通过了。。。就是暴力法。。

但是不应该,因为矩阵已经是排过序的了,这点完全没用上

可以逐行使用二分法:(妈呀我对这些库里函数好陌生啊。。。前面那个就是连Math.max(a,b)判大小我都没想到可以用

public boolean searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
            return false;
        for (int i = 0; i < matrix.length; i++) {
if (matrix[i][0] > target)//如果最小的数都大于target,则false return false;
if (Arrays.binarySearch(matrix[i], target) >= 0)//一维数组的二分法,输入数组和要搜索的值,返回索引号 return true; } return false; } 作者:ustcyyw 链接:https://leetcode-cn.com/problems/search-a-2d-matrix-ii/solution/240java-san-chong-fang-fa-xiang-jie-zui-you-jie-yo/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这题还有更好的搜索解法,有空再看。。。

5. 有序矩阵的 Kth Element

378. Kth Smallest Element in a Sorted Matrix ((Medium))

Leetcode / 力扣

给定一个 n x n 矩阵,其中每行和每列元素均按升序排序(但并不是遍历的顺序递增),找到矩阵中第k小的元素。
请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。

我的想法是遍历出来放数组或容器里再从小到大排序拿,但这一定不是个好解法,直接看答案吧。。。(答案是放入优先队列中保留最小的k个。。。

2种解法

1.优先队列的使用

思路分析:

要找第k小的元素,一种最常规的做法就是使用优先队列

第1个知识点:

最大优先队列,无论入队顺序,当前最大的元素优先出队。

最小优先队列,无论入队顺序,当前最小的元素优先出队。

二叉堆的特性:

1.最大堆的堆顶是整个堆中的最大元素

2.最小堆的堆顶是整个堆中的最小元素

因此,我们可以用最大堆来实现最大优先队列,每一次入队操作就是堆的插入操作,每一次出队操作就是删除堆顶节点

https://www.cnblogs.com/wmyskxz/p/9301021.html

找第k小的元素,就保留k个最小的元素,其中最大的那个就是答案,所以可以使用最大优先队列
遍历矩阵中的元素,将元素添加到队列中,如果队列中元素数目MaxPQ.size() > k,就将堆点最大的元素弹出。
遍历结束后弹出堆顶元素,就是最小的k个元素中最大的,即第k小的元素。
这里可以利用矩阵的有序性做一点小的优化
如果在遍历的过程中,队列中的元素数目已经为k了,且如果当前元素大于堆顶元素,这个元素放入队列中还会被弹出,所以就没必要放入。
并且遍历的内循环是从某一行的从左到右遍历,当前元素的右边元素比当前元素更大,也没必要放入队列,所以当MaxPQ.size() == k && num > MaxPQ.peek(),直接打断内循环,进行下一行的遍历。

作者:ustcyyw
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/solution/378java-er-fen-fa-tu-jie-you-xian-dui-lie-liang-ch/

public int kthSmallest(int[][] matrix, int k) {
        PriorityQueue<Integer> MaxPQ = new PriorityQueue<>(Collections.reverseOrder());
        //知识点1:优先队列  知识点2:Conllections.reverseOrder()方法,这里是用来实现最大优先队列
        for (int[] row : matrix) {
            for (int num : row) {//嵌套逐行遍历得到元素们
                
                if (MaxPQ.size() == k && num > MaxPQ.peek())//优化的部分!!!已经有了k个小的,那么大的不看了换下一行
                    break;//跳出第二个嵌套 换一行元素进行添加
                
                MaxPQ.add(num);
if (MaxPQ.size() > k) MaxPQ.remove();//去掉的总会是最大的 直到只剩k个
} } return MaxPQ.remove(); }

里面用的foreach嵌套!!!!

第2个知识点:

reverseOrder() 方法用于获取一个比较有否就实现Comparable接口的对象的集合的自然顺序相反。

返回值:在方法调用返回一个比较器,它强行上实现Comparable接口的对象的集合的自然顺序相反

例子:

package com.yiibai;

import java.util.*;

public class CollectionsDemo {
   public static void main(String args[]) {  
      // create linked list object         
      LinkedList list = new LinkedList();  
      
      // populate the list 
      list.add(-28);  
      list.add(20);  
      list.add(-12);  
      list.add(8);  
      
      // create comparator for reverse order
      Comparator cmp = Collections.reverseOrder();  

      // sort the list
      Collections.sort(list, cmp);  //这里又是一个知识点 sort方法排序 
          
      System.out.println("List sorted in ReverseOrder: ");      
      for(int i : list){
         System.out.println(i+ " ");
      }    
   }
}//原文出自【易百教程】,商业转载请联系作者获得授权,非商业请保留原文链接:https://www.yiibai.com/java/util/collections_reverseorder.html

输出是从大到小的值

最小优先队列则是自然排序,就不用知识点2的帮助了,输出从小到大的值,封顶peek是最小值

6. 一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数

645. Set Mismatch (Easy)

Leetcode / 力扣

它有可能重复了2两次但是丢失的是20,这也不相邻,嵌套也不好做,想不出。。。

啊!对1到length每个数计数?普通数为1,重复数为2,丢失数为0。代码怎么写啊。。。

暴力法的代码都想不出。。。

看了答案,暴力法计数就是用嵌套for循环做遍历,i 是1到n(重复的和丢失的,任何数都走一遍,是正确的数据集)

但是!!!j 不是从i+1后面开始,而是对于每一个 i 都要从 j=0重新遍历。

则 i 对应重复的那个,进入 j 后会count=2;对应丢失的那个,会count=0

public class Solution {
    public int[] findErrorNums(int[] nums) {
        int dup = -1, missing = -1;
        for (int i = 1; i <= nums.length; i++) {//搜索范围就把所有都包括了,每个数1次,这是用数,1到n挨个儿判断
            int count = 0;
            for (int j = 0; j < nums.length; j++) {//这是用索引指的元素值
                if (nums[j] == i)//i是正确数据集 nums是错误数据集 
//其实就是每个正确的数遍历拿出 都和错误的数据集疯狂走一遍对比 大部分count=1 count
++; }
if (count == 2) dup = i; else if (count == 0) missing = i; if (dup > 0 && missing > 0)//优化的部分 break; } return new int[] {dup, missing}; } }

方法二:使用排序数组方法Araays.sort(nums)排好序后,遍历数组普通的前后相差1,若前等于后则该值重复,若前后相差大于1,则丢失的是前数加1。

class Solution {
    public int[] findErrorNums(int[] nums) {
        int length = nums.length;
        Arrays.sort(nums);
        int a=-1,b=1;//为啥b=1,因为考虑nums=[2,2]时
        for(int i = 1;i<length;i++){
            if(nums[i]==nums[i-1]){//不能用i+1,会越界空指针异常 所以用i-1,对应i从1开始
                a=nums[i];
            }
            if(nums[i]-nums[i-1]>1){
                b=nums[i-1]+1;
            }

        }
        return new int[] {a, nums[length-1]==length?b:length};//要考虑丢失的是最末位时该值根本不在数组里 因为这里没有1到n挨个儿判断
    }
}

还有个方法用Map存值和出现次数,如果我们知道 nums 中每个数字出现的次数,就可以轻松的解决问题。

使用 map存储nums的值(key)和每个数字的出现次数。存储形式为 (num_i, count_i)表示数字 num_i 一共出现了 count_i 次。当一个元素重复出现时,它的计数就加 1。

再检查 1 到 n的每个数字在 map 中出现次数。如果一个数字在 map 中没有出现,它就是缺失数字。如果一个数字的出现了两次,它就是重复数字。

public class Solution {
    public int[] findErrorNums(int[] nums) {
        Map < Integer, Integer > map = new HashMap();
        int dup = -1, missing = 1;//还是单拎[2,2] 缺的1
        for (int n: nums) {
            map.put(n, map.getOrDefault(n, 0)+1);//知识点1 意思是取key为n的值,若不存在则用0代替。则不重复的普通就是放入n和0+1,重复的就是n和1+1
        }
for (int i = 1; i <= nums.length; i++) {//i从1到n挨个儿判断 if (map.containsKey(i)) {//知识点2 判断是否包含指定的键名,返回布尔值 包含的话看是1还是2 不包含的话就是缺失的 if (map.get(i) == 2) dup = i;//用的值,不是索引!!搞清楚map里存的是值,这里i也是1到n的值 } else  //即不包含i这个key missing = i; } return new int[]{dup, missing}; } }

关于知识点1map.getOrDefault(n, 0)https://blog.csdn.net/weixin_43263961/article/details/86513880

关于知识点2map.containsKey(i)https://blog.csdn.net/weixin_40797576/article/details/78874657

方法五:使用额外数组
算法

在 方法四 中使用 map 存储每个数字出现的次数,每个数字都需要两个变量分别存储数字本身和出现次数,因此存储 n 个数字和出现次数需要 2n 的空间。如果使用数组 arr 代替 map,可以将空间减少到 n。

在数组 arr 中,索引代表数字,arr 存储每个数字出现的次数。例如 arr[i]存储数字 i出现的次数。其他过程与 方法四 相同。

有空再研究吧这题方法也太多了-------------------------------------------------------------

7. 找出数组中重复的数,数组值在 [1, n] 之间

287. Find the Duplicate Number (Medium)

Leetcode / 力扣

要求不能修改数组,也不能使用额外的空间。

可以依然用上面的三种方法吧?用Map试试

class Solution {
    public int findDuplicate(int[] nums) {
        Map<Integer,Integer> map = new HashMap();
        int length = nums.length;
        int a =-1;

        for(int res:nums){
            map.put(res,map.getOrDefault(res,0)+1);
        }
        for(int i =1;i<=length;i++){
            if(map.containsKey(i)){
                if(map.get(i)>1){//因为它有可能不止重复一次 比如nums=[2,2,2,2]
                    a=i;
                }
            }
        }
        return a;
    }
}

8. 数组相邻差值的个数

667. Beautiful Arrangement II (Medium)

Leetcode / 力扣

给定两个整数 n 和 k,你需要实现一个数组,这个数组包含从 1 到 n 的 n 个不同整数,同时满足以下条件:

① 如果这个数组是 [a1, a2, a3, ... , an] ,那么数组 [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] 中应该有且仅有 k 个不同整数;.

② 如果存在多种答案,你只需实现并返回其中任意一种.

------------------------------------------------------------------------------

这实在是没有想法。。看答案吧

找出规律,然后填充数组,但是java没有像c++的push_back填充,不能用Arrays.fill(number, i); 这会把数组全部填充了

我们得用容器才行。。但是也可以用对应的索引往里填。。。

不太会,先跳

----------------------------------------------------------------------

9. 数组的度

697. Degree of an Array (Easy)

Leetcode / 力扣

Input: [1,2,2,3,1,4,2]
Output: 6

给定一个非空且只包含非负数的整数数组 nums, 数组的度的定义是指数组里任一元素出现频数的最大值。

你的任务是找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。

-------------------------------------------------------------------------------

这我只会找到度,用前面的count存map里遍历key为数组的值来取出。再用Math.max找到最大的count

然后取最短连续子数组的值就想不通了。。。

看答案是再搞2个map。。。一个存第一次出现的索引,一个存最后一次出现的索引。。。一共3个map。。。

还有一个新知识点1int degree = Collections.max(count.values());直接可得集合中最大的元素

非常有用,省得我再用循环去找int max = Math.max(max,res); 这里第3题用的遍历数组找连续1出现的最大次数。

知识点2: for (int x: count.keySet())遍历 map.keySet()方法获取map的key的名称为一个set视图(像是个数组?

class Solution {
    public int findShortestSubArray(int[] nums) {
        Map<Integer, Integer> left = new HashMap(),
            right = new HashMap(), count = new HashMap();

        for (int i = 0; i < nums.length; i++) {//遍历数组 
            int x = nums[i];
            if (left.get(x) == null) left.put(x, i);//只存最初的值和索引号 值只有初始的,这里也可以用(!left.containsKey(x))
            right.put(x, i);//不断更新的,存住的是最后出现的值对应的索引号 值会更新
            count.put(x, count.getOrDefault(x, 0) + 1);//这是熟悉的存值和count操作 值会累加
        }

        int ans = nums.length;
        int degree = Collections.max(count.values());//度是最大出现次数
//已知值,如何找对应的键x?答:遍历所有键找
for (int x: count.keySet()) {//遍历键们(键是存的数组的元素,所以这里遍历数组也一样 但这个比数组元素少因为重复的元素作为键只能存一次 if (count.get(x) == degree) {//找到x为度对应的元素值!!!这里主要是找到这个x键即元素值 ans = Math.min(ans, right.get(x) - left.get(x) + 1); } } return ans; } } 作者:LeetCode 链接:https://leetcode-cn.com/problems/degree-of-an-array/solution/shu-zu-de-du-by-leetcode/

答案的思路分析:

具有度数 d 的数组必须有一些元素 x 出现 d 次。如果某些子数组具有相同的度数,那么某些元素 x (出现 d 次)。最短的子数组是将从 x 的第一次出现到最后一次出现的数组。
对于给定数组中的每个元素,让我们知道 left 是它第一次出现的索引; right 是它最后一次出现的索引。例如,当 nums = [1,2,3,2,5] 时,left[2] = 1 和 right[2] = 3。
然后,对于出现次数最多的每个元素 x,right[x] - left[x] + 1 将是我们的候选答案,我们将取这些候选的最小值。

10. 对角元素相等的矩阵

766. Toeplitz Matrix (Easy)

Leetcode / 力扣

如果一个矩阵的每一方向由左上到右下的对角线上具有相同元素,那么这个矩阵是托普利茨矩阵。

给定一个 M x N 的矩阵,当且仅当它是托普利茨矩阵时返回 True。

看答案的分析:

观察矩阵其实很容易发现,满足托普利茨矩阵定义的矩阵,从第二行开始,每个元素都与左上角的元素相等。
所以只需要一个二层嵌套循环,外层循环从第二行开始,内层循环从每行的第二个元素开始(因为第一行,以及其余行的第一个元素都是没有左上角元素的)。如果循环过程中有一组元素不相等,即不满足条件,返回false。
由于两层循环,遍历了除第一行及每行第一个元素外的所有元素,所以时间复杂度为O((n−1)(m−1));每次仅使用了两个元素,空间复杂度为O(1)。

所以其实就是抛开第一行第一列(等于啥都行,但它们的右下角元素要满足等于它们,这在后面可以判断)双层嵌套遍历矩阵得到当前元素nums[i][j],与它左上角的元素nums[i-1][j-1]进行对比。。。。

public boolean isToeplitzMatrix(int[][] matrix) {
        int column = matrix[0].length;
        for (int i = 1; i < matrix.length; i++) {
            for (int j = 1; j < column; j++) {
                if (matrix[i][j] != matrix[i - 1][j - 1])
                    return false;
            }
        }
        return true;
    }

作者:ustcyyw
链接:https://leetcode-cn.com/problems/toeplitz-matrix/solution/766java-mei-ci-jin-shi-yong-liang-ge-yuan-su-by-us/

 

 ustcyyw作者好厉害!!!!

11. 嵌套数组

565. Array Nesting (Medium)

Leetcode / 力扣

索引从0开始长度为N的数组A,包含0到N - 1的所有整数。找到最大的集合S并返回其大小,其中 S[i] = {A[i], A[A[i]], A[A[A[i]]], ... }且遵守以下的规则。

假设选择索引为i的元素A[i]为S的第一个元素,S的下一个元素应该是A[A[i]],之后是A[A[A[i]]]... 以此类推,不断添加直到S出现重复的元素。

-------------------------------------------------------------------------------

勉强看懂题目,怎么解真是一头雾水。。。用Map集合??找最长的是通过把每个元素都为k试一下??不对,是嵌套就可以解决,在第二层拿到元素变成索引得到的元素有无,有的话也不用拿,在第二层计数就可以!!!!第一层是遍历用每一个为k这个想对了....然后计数之间的比较要想到用max=Math.max(max,count)

题目描述:S[i] 表示一个集合,集合的第一个元素是 A[i],第二个元素是 A[A[i]],如此嵌套下去。求最大的 S[i]

即前一个元素变后一个索引1001

public int arrayNesting(int[] nums) {
    int max = 0;
    for (int i = 0; i < nums.length; i++) {S[i] i个循环nums[i]为开头
        int cnt = 0; //换一个k就开启它的计数
        for (int j = i; nums[j] != -1; ) {//看到这里,我发现我第一题不把for变成while原来也是可行的 
//这个for循环就只有初始值和条件,步长在循环内也可以 这里是遍历数组让他们挨个儿开头为k
cnt
++;//长度 int t = nums[j]; nums[j] = -1; // 标记该位置已经被访问 j = t;//元素值变索引在这里实现 } max = Math.max(max, cnt); } return max; }

12. 分隔数组

769. Max Chunks To Make Sorted (Medium)

Leetcode / 力扣

数组arr是[0, 1, ..., arr.length - 1]的一种排列,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果按升序排序后的原数组相同。

我们最多能将数组分成多少块?

emmmm没看懂题目。。。

题目描述:分隔数组,使得对每部分排序后数组就为有序

要得到最多能分为几块,就要尽可能将区间分得细碎,每一个小区间都需要保证,小区间的右边界索引刚好是小区间内最大的元素的值,否则无法还原成升序数组
有了这个指导思想,可以通过双指针一次遍历数组得到答案

作者:ustcyyw
链接:https://leetcode-cn.com/problems/max-chunks-to-make-sorted/solution/769java-shuang-zhi-zhen-da-bai-100-tu-jie-xiang-ji/


有点不太明白....先跳了

-----------------------------------------------------------------------------------------------------------------------------------

 

 

 

 

 

posted @ 2020-05-28 15:15  xinxinpang  阅读(280)  评论(0编辑  收藏  举报