leetocde 904. Fruit Into Baskets

In a row of trees, the i-th tree produces fruit with type tree[i].

You start at any tree of your choice, then repeatedly perform the following steps:

  • Add one piece of fruit from this tree to your baskets. If you
    cannot, stop.

  • Move to the next tree to the right of the current tree. If there is
    no tree to the right, stop.

Note that you do not have any choice after the initial choice of starting tree: you must perform step 1, then step 2, then back to step 1, then step 2, and so on until you stop.

You have two baskets, and each basket can carry any quantity of fruit, but you want each basket to only carry one type of fruit each.

What is the total amount of fruit you can collect with this procedure?

Example 1:

Input: [1,2,1]
Output: 3
Explanation: We can collect [1,2,1].

Example 2:

Input: [0,1,2,2]
Output: 3
Explanation: We can collect [1,2,2].
If we started at the first tree, we would only collect [0, 1].

Example 3:

Input: [1,2,3,2,2]
Output: 4
Explanation: We can collect [2,3,2,2].
If we started at the first tree, we would only collect [1, 2].

Example 4:

Input: [3,3,3,1,2,1,1,2,3,3,4]
Output: 5
Explanation: We can collect [1,2,1,1,2].
If we started at the first tree or the eighth tree, we would only collect 4 fruits.

Note:

1 <= tree.length <= 40000
0 <= tree[i] < tree.length

想了好久,没想到比较好的方法,于是乎秉着稳神:“能过题的程序都是好程序!”的一贯作风,写了一道比较迷的模拟。。。
现在有一个果园,种着很多不同的树,但只有一排。现在要在一段连续果树上,摘两种果子。且这段果树只能有这两种果子。问从哪里开始摘,能摘的最多。
模拟如下过程:

  1. 从树上摘一个果子,放入篮子1
  2. 移动到下一棵树,如果下一棵树的果子和篮子1中的果子种类相同,执行 3 ;不同,执行 4
  3. 摘到的果子数 num + 1, 执行2
  4. 摘下果子放入篮子2,num + 1,并记住当前果树的位置 pos
  5. 移动到下一棵树,判断果子的种类是否与篮子 1 或 篮子 2 相同。如果相同,执行 6 ;不同,执行 7
  6. 摘到的果子数 num + 1,执行5
  7. 比对是否为最大值,后将 num 置零
  8. 把所有篮子中的果子都扔掉,返回位置 pos ,执行 1

这是最初的思路,存在可以改进的地方。比如模拟过程中的 pos 变量,可以改为记录 篮子 1 中的果子种类,最后一次出现的位置,初始值为篮子 2 中果子第一次出现的位置


class Solution {
public:
    int totalFruit(vector<int>& tree) {
        if(tree.size()==0)
            return 0;
        if(tree.size()==1)
            return 1;
        int basket1=tree[0],basket2=-1;
        int tempNum=0,num=0;
        int pos=0;
        for(register int i=0;i<tree.size();i++){
            if(basket1==tree[i]){
                tempNum++;
                
            }else{
                basket2=tree[i];
                pos=i;
                for(register int j=i;j<tree.size();j++){
                    if(tree[j]==basket1)
                        pos=j;
                    if(tree[j]==basket1 || tree[j]==basket2){
                        tempNum++;
                        continue;
                    }else
                        break;
                }
                num=max(num,tempNum);
                if(pos==i)
                    tempNum=1;
                else{
                    tempNum=0;
                    i=pos-1;
                }
                basket1=tree[pos];
            }
        }
        num=max(num,tempNum);
        return num;
    }
};

关于可能错误的几点说明:

  • 仅执行过外层循环
    而且恰巧更新最大值的操作又是写在内层循环中,导致程序返回值为 0 ,或 返回变量的初始值
    Array: [1,1,1,1,1]

  • 进入内层循环时,未初始化 pos 。
    如果仅仅依靠,在内层循环中出现种类 1 来更新 pos 。当内层循环未出现种类 1 时,pos 变量不更新,进而程序在区间 [ pos , j )之间产生死循环

     Array: [1,2,3,1,2,3]
    
  • 内层循环达到数组末尾
    此时可以保证,再继续进行程序不会产生更大的区间长度值。所以提前退出循环,并返回结果

  • 所给数组为空

注意程序中的判断条件,考虑这个条件是否一定发生,如果未发生将产生什么影响。循环起始状态和结束状态是否正确。特殊输入是否正确。

猜你喜欢

转载自blog.csdn.net/white_156/article/details/82759692
今日推荐