对于“递减元素使数组呈锯齿状”题目的思考

一.算法题干

给你一个整数数组nums,每次操作会从中选择一个元素并将该元素的值减少1。
如果符合下列情况之一,则数组A就是锯齿数组:
每个偶数索引对应的元素都大于相邻的元素,即A[0] > A[1] < A[2] > A[3] < A[4] > …
或者,每个奇数索引对应的元素都大于相邻的元素,即 A[0] < A[1] > A[2] < A[3] > A[4] < …
返回将数组nums转换为锯齿数组所需的最小操作次数。

二.解题思路

这道题的解题思路相对来说比较简单。首先根据题目中所定义的“锯齿数组”分的两种情况,我也相应地分两种情况进行讨论。首先假定构造出偶数索引大于相邻元素的数组,则遍历所有偶数索引的值,将该值与相邻值进行比较,让相邻值减去一个数,使之恰好小于该偶数索引对应的值,将这个减去的数累加到最后结果上。奇数索引同理。这里需要注意的是两个边界条件要进行单独判断处理。对两种情况分别求完结果后,返回较小值即为所求。

三.实现代码

int movesToMakeZigzag(vector<int>& nums) {
	vector<int> ns=nums;
	int minv=0,l=ns.size(),minv1=0;
	if(l==1) return 0;
	for(int i=0;i<l;i+=2)
	{
    	if(i==0)
	    {
	        if(ns[i]<=ns[i+1])
	        {
	            minv+=ns[i+1]-ns[i]+1;
	            ns[i+1]=ns[i]-1;
	        }
	    }
	    else if(i==l-1)                
	    {
	        if(ns[i]<=ns[i-1])
	        {
	            minv+=ns[i-1]-ns[i]+1;
	            ns[i-1]=ns[i]-1;
	        }
	    }
	    else
	    {
	        if(ns[i]<=ns[i+1])
	        {
	            minv+=ns[i+1]-ns[i]+1;
	            ns[i+1]=ns[i]-1;
	        }
	        if(ns[i]<=ns[i-1])
	        {
	            minv+=ns[i-1]-ns[i]+1;
	            ns[i-1]=ns[i]-1;
	        }
	    }
	}
	ns=nums;
	for(int i=1;i<l;i+=2)
	{
	    if(i==l-1)
	    {
	        if(ns[i]<=ns[i-1])
	        {
	            minv1+=ns[i-1]-ns[i]+1;
	            ns[i-1]=ns[i]-1;
	        }
	    }
	    else
	    {
	        if(ns[i]<=ns[i+1])
	        {
	            minv1+=ns[i+1]-ns[i]+1;
	            ns[i+1]=ns[i]-1;
	        }
	        if(ns[i]<=ns[i-1])
	        {
	            minv1+=ns[i-1]-ns[i]+1;
	            ns[i-1]=ns[i]-1;
	        }
	    }
	}
	return min(minv,minv1);
}

四.对比分析

public int movesToMakeZigzag(int[] a) {
	int n = a.length;
	int c = 0;
	for(int i = 1;i < n;i+=2){
		int to = a[i-1]-1;
        if(i+1 < n)to = Math.min(to, a[i+1] - 1);
        if(a[i] < to)continue;
        c += a[i] - to;
    }
    int d = 0;
    for(int i = 0;i < n;i+=2){
    	int to = 999999999;
      	if(i-1 >= 0)to = Math.min(to, a[i-1]-1);
      	if(i+1 < n)to = Math.min(to, a[i+1] - 1);
      	if(a[i] < to)continue;
      	d += a[i] - to;
    }
    return Math.min(c, d);
}

这段代码是使用Java实现该算法的,其思路和我的思路主要不同点在于,它是先找出左右两个相邻值中的最小值,然后根据最小值来计算差值。其优点在于代码显然比我的要简洁不少。

五.题目来源

递减元素使数组呈锯齿状

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。首先需要明确一下,emu8086是一款8086/8088微处理器的模拟器,用于编写和调试汇编语言程序。针对你的问题,需要编写汇编程序实现将两组递减有序的数组排成一组递增有序的数组。 以下是一份示意的汇编代码,可以实现将两组递减有序的数组排成一组递增有序的数组: ``` DATA SEGMENT ARRAY1 DB 5, 4, 3, 2, 1 ;第一组递减有序数组 ARRAY2 DB 10, 9, 8, 7, 6 ;第二组递减有序数组 RESULT DB 10 DUP(0) ;排好序的递增有序数组 DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA START: MOV AX, DATA ;初始化数据段寄存器 MOV DS, AX MOV CX, 10 ;循环计数器,共10个元素 MOV SI, 4 ;移动到第一组数组的最后一个元素 MOV DI, 8 ;移动到第二组数组的最后一个元素 DEC CX ;循环计数器减1 L1: CMP ARRAY1[SI], ARRAY2[DI] ;比较两个数组对应元素大小 JAE COPY1 ;如果第一组数组的当前元素大于等于第二组数组的当前元素,就拷贝到结果数组中 JMP COPY2 ;如果第二组数组的当前元素大于第一组数组的当前元素,也拷贝到结果数组中 COPY1: MOV AL, ARRAY1[SI] ;将第一组数组的当前元素拷贝到AL寄存器中 MOV RESULT[SI+DI-4], AL ;将AL寄存器中的值拷贝到结果数组中 DEC SI ;移动到下一个元素 CMP SI, 0 ;如果第一组数组已经处理完,直接拷贝第二组数组元素到结果数组中 JZ FINISH JMP L1 COPY2: MOV AL, ARRAY2[DI] ;将第二组数组的当前元素拷贝到AL寄存器中 MOV RESULT[SI+DI-4], AL ;将AL寄存器中的值拷贝到结果数组中 DEC DI ;移动到下一个元素 CMP DI, 0 ;如果第二组数组已经处理完,直接拷贝第一组数组元素到结果数组中 JZ FINISH JMP L1 FINISH: MOV AH, 4CH ;程序结束指令 INT 21H CODE ENDS END START ``` 以上代码实现了将两组递减有序的数组排成一组递增有序的数组。请将代码复制到emu8086中进行测试,如果有问题请随时向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值