通过减少相邻元素对的数量来生成零数组

data structurec++programming

问题描述包括通过减少相邻元素对的数量来生成零数组。

输入中给出了一个数组,我们可以对该数组执行以下操作:从第 i 个元素和第 (i+1) 个元素的索引中减 1,其中 0<=i<(数组大小-1)。我们可以根据需要多次执行给定的操作,直到数组元素变为零。该数组只包含正整数。

在本题中,我们将在输入中给出一个数组,我们需要检查执行上述操作(任意次数)后,是否可以将所有数组元素转换为零。如果数组中的所有元素都可以通过执行任意数量的操作转换为零,则我们需要打印"Yes",否则我们需要打印"No"。

让我们尝试通过以下示例来理解这个问题。

输入

a[]={1,2,5,4}

输出

YES

解释- 对数组应用操作后,它变为

{1,2,5,4}={0,1,5,4}={0,0,4,4

对 a[2] 和 a[3] 应用 4 次操作后,我们得到 {0,0,0,0}。

由于,该数组可以转换为零数组通过任意次数应用指定的操作,输出为"是"。

输入

a[]={3, 2, 2, 6}

输出

No

解释- 对数组应用该操作

{3,2,2,6}={2,1,2,6}={1,0,2,6}={1,0,1,5}={1,0,0,4}

由于我们只能从 a[i] 和 a[i+1] 中减 1,无法进一步执行该操作,并且该数组无法转换为零数组。因此,输出为"否"。

有多种方法可以解决这个问题,即通过任意次数地应用指定的操作来检查数组是否能够转换为零数组。让我们看看并理解解决这个问题的有效方法。

方法 1

如果数组中奇数位置元素的总和等于偶数位置元素的总和,则数组可以转换为零数组。由于我们只能从 i 和 (i+1) 位置减 1,因此要通过从奇数位置和偶数位置减 1 来使数组成为零数组,只有当奇数位置元素之和等于偶数位置元素之和时才有可能。

例如,{1,2,5,4} 可以转换为零数组。

奇数位置元素之和,即 a[1]+a[3]=2+4=6

偶数位置元素之和,即 a[0]+a[2]=1+5=6

因此,它可以转换为零数组。

我们使用此逻辑来检查是否可以通过在我们的方法中减少相邻对来将数组转换为零数组。

在 C++ 中实现该方法的步骤如下:

  • 我们将编写一个函数,通过计算偶数位置和奇数位置的和来检查数组是否可以转换为零数组。

  • 初始化两个变量,分别存储偶数位置和奇数位置的数字和。

  • 使用 for 循环从 i=0 迭代到 i

  • 在 for 循环中迭代时,我们将检查 i 是否为偶数,如果为偶数,则将第 i 个位置的对应元素添加到用于存储偶数位置数字和的变量中;如果 i 不是偶数,则将第 i 个位置的对应元素添加到另一个用于存储奇数位置数字和的变量中。

  • 迭代整个数组后,我们将通过比较变量中存储的值来检查偶数位置和奇数位置的数字和是否相等。

  • 如果两者相等,则返回 true,否则返回false。

  • 如果函数返回 true,我们将在输出中打印"Yes",否则我们将打印"N0"。

示例

//C++ 代码,用于检查是否可以通过将相邻对减 1 将数组转换为零数组

#include<bits/stdc++.h>

using namespace std;

//检查数组是否可以转换为零数组的函数
bool check(int a[],int N){
    int even_sum=0; //存储偶数位置元素的和
    int odd_sum=0; //存储奇数位置元素的和
    
    //计算偶数位置和奇数位置元素的和
    for(int i=0;i<N;i++){
        
        //如果 i 是偶数
        if(i%2==0){
            even_sum += a[i];
        }
        else{
            odd_sum += a[i];
        }
    }
    
    if(even_sum==odd_sum){ //如果偶数位置的总和等于奇数位置的总和,则返回 true
        return true;
    } else{
        return false;
    }
}

int main()
{
    int a[]={2,8,3,12,5,9,17,8,8,11};
    int N; //存储数组的大小
    N=sizeof(a)/sizeof(a[0]);
    //调用函数
    if(check(a,N)==true){
        cout<<"Yes"<<endl;
    } else{
        cout<<"No"<<endl;
    }

    return 0;
}

输出

No

时间复杂度− O(N),因为我们在数组中迭代存储偶数位置和奇数位置的数字之和。

空间复杂度− O(1),因为该方法不占用额外空间。

方法 2

在此方法中,我们将检查给定数组所构成的数字。如果数组组成的数字是 11 的倍数,则可以通过从 a[i] 和 a[i+1] 中减 1 任意次,将数组转换为零数组。如果给定数组组成的数字不是 11 的倍数,则该数组无法转换为零数组。

例如,数组为 {3,2,2,6}。

数组组成的数字为 3226。由于该数字不是 11 的倍数,因此该数组无法转换为零数组。

如果给定数组为 {1,2,5,4}。

数组组成的数字为 1254。该数字是 11 的倍数,因为 11*114 等于 1254。因此,可以通过执行以下运算将数组转换为零数组。

执行以下步骤C++ 中的方法:

  • 我们将创建一个函数来检查给定数组组成的数字是否是 11 的倍数。

  • 初始化一个变量来存储数组组成的数字。

  • 我们将在 for 循环中从 i=0 迭代到 i

  • 一旦我们获得数组组成的数字,我们将检查它是否可以被 11 整除。如果能被 11 整除,则打印 Yes,因为生成的数字是 11 的倍数;否则打印 No。

注意:此方法仅适用于大小小于或等于 18 的数组,因为数组生成的数字可能会溢出数据类型。

示例

// C++ 代码,用于检查数组是否可以转换为零数组
// 通过减少相邻的

#include <bits/stdc++.h>

using namespace std;

//函数检查给定的数组是否可以转换为零数组
bool check(int a[], int N)
{
    // 存储给定数组构成的数字
    long long number = 0;
    for (int i = 0; i < N; i++){
        //更新数字
        number = number * 10 + a[i];
    }
    
    //如果 number 是 11 的倍数,则它可以被 11 整除
	if(number%11==0){
	    return true;
	} else{
	    return false;
	}
}

int main()
{
	int a[] = {2,5,1,3,6,1 };
	int N = sizeof(a) / sizeof(a[0]); //计算数组大小

    //调用函数
	if (check(a, N)){
		cout << "Yes"<<endl;
	} else{
		cout << "No"<<endl;
	}
}

输出

Yes

时间复杂度− O(N),因为我们在给定数组中迭代以获取数组构成的数字。

空间复杂度− O(1),因为该方法不占用额外空间。

结论

本文讨论了通过递减相邻对的对数来检查给定数组是否能转换为零数组的问题。我们尝试使用 C++ 中的两种不同方法解决这个问题,它们都采用了简单的逻辑,运行时间复杂度为 O(N),占用空间也为常数。

希望您在阅读本文后能够理解这个问题以及解决问题的方法。


相关文章