?
思路:使用索引法。
用HashMap存储各种值所在位置,key为数据的值,value为数据的所在数组的下标。TreeSet存放数据,即p的取值。(TreeSet中存放的内容自动升序排序且唯一) 开始的时候,为原始数组,当左边为0,右边非0时,非零段加1(最左边的数除外),为了统一特殊情况,从下标为1的地方开始放置数据,下标为0的地方设置为0。然后,遍历p的取值,划分数组a。如果a[i]位置置为0,那么如果原先a[i-1]=0并且a[i+1]=0则划分段数减一;如果a[i]位置置为0,那么如果原先a[i-1]>0并且a[i+1]>0则划分段数加一;其他情况则段数不变。当数组中的最后一个数需要设置为0时,由于需要用到a[i+1]的值,所以在原数组a后再添加一个数据0(不影响结果),以防止数组越界。
import java.util.*;
public class Main {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[n+2];
a[0] = 0;
a[n+1] = 0;
TreeSet<Integer> all = new TreeSet();
HashMap<Integer, ArrayList<Integer>> b = new HashMap<>();
for(int i = 1; i < n + 1; i++){
a[i] = in.nextInt();
if(b.containsKey(a[i])){
//已有a[i]则直接加入索引
b.get(a[i]).add(i);
}else{
//a[i]不存在
ArrayList<Integer> tpm = new ArrayList();
tpm.add(i);
b.put(a[i],tpm);
}
if(a[i] != 0)
all.add(a[i]);
}
int sum = 0;//统计p=1时的非零段
for(int i = 1; i <= n; i++){
if((a[i] > 0) && (a[i - 1] == 0)) sum++;
}
int last = sum;//记录上一次操作后的结果
for(int curp:all){
int tmp = last;//tmp记录这次操作后的结果
for(int i = 0; i < b.get(curp).size(); i++){
int pos = b.get(curp).get(i);
a[pos] = 0;
if(0 < a[pos - 1] && 0 < a[pos + 1])
++tmp;
if(a[pos - 1]==0 && a[pos + 1]==0)
--tmp;
}
sum = Math.max(sum, Math.max(last, tmp));
last = tmp;
}
System.out.print(sum);
}
}
|