已知一个数组a[N]来构造数组b[N]的有趣算法题

给定一个数组a[N],我们希望构造数组b[N],其中b[i]=a[0]*a[1]*...*a[N-1]/a[i]。
在构造过程要求满足:
1、不使用除法;
2、O(1)空间复杂度和O(n)时间复杂度;
3、除遍历a[N] b[N]使用的计数器外,不使用任何新的变量(包括栈临时变量、对空间和全局静态变量等);

/**********************************************/
/*
给定一个数组a[N],我们希望构造数组b[N],其中b[i]=a[0]*a[1]*...*a[N-1]/a[i]。
在构造过程:
1不允许使用除法;
2要求O(1)空间复杂度和O(n)时间复杂度;
3除遍历计数器与a[N] b[N]外,不可使用新的变量(包括栈临时变量、对空间和全局静态变量等);
*/
/**********************************************/
void makeArray(int a[],int b[],int len)
{
	int i,j;
	b[0] = 1;

	for(i=1;i<len;i++)
	{
		b[i] = b[i-1]*a[i-1];   //累乘a[0]*a[1]...a[i-1]
	}

	b[0] = a[len-1];
	for(j=len-2;j>0;j--)
	{
		b[j] *= b[0];
		b[0] *= a[j];
	}
}

  这道题目很常见,我看完之后分析了一下,如果在b[N]中,要求b[i]=a[0]*a[1]*...*a[N-1]/a[i],那么我们可以分开考虑,实现代码用了两个循环,前一个循环先来实现,

b1[i]=a[0]a[1]a[2]…a[i-1],后一个循环从后往前来实现b2[i]=a[len-1]a[len-2]…a[i+1],在第二个循环中由于b[0]的不断变化,实现了b[i]=b1[i]*b2[i],所以才实现了题目要求,由于题目中不允许再定义变量可以将b[0]多次使用。

时间: 2024-07-30 10:17:53

已知一个数组a[N]来构造数组b[N]的有趣算法题的相关文章

已知一个数组,求数组中心元素

/** * */package Student_System;import java.util.*;import java.util.*;/**Homework11 * *Homework1101 *已知一个数组,求数组中心元素 * @author 读你一世 * * QQ: 1816274408 *2017年4月11日上午10:25:03 * */public class Homework1101 { public static void main(String[] args){ Scanner

编程题:已知一个一维数组a[10]中有10个数,求出第m个数到第n个数的和。其中m、n由键盘输入。

#include<stdio.h> int sum(int *q,int n) { int i,s=0; for(i=0;i<n;i++,q++) s+=*q; return s; } void main() { int n,m,a[10]={1,2,3,4,5,6,7,8,9,10}; int *p; printf("Please input m and n(m<n<10):\n"); scanf("%d,%d",&m,&am

编程题:指针变量,实参与形参的引用。已知一个一维数组,求其中前n个数的和。n由键盘输入。

#include<stdio.h> int sum(int *q,int n) { int i,s=0; for(i=0;i<n;i++,q++) s+=*q; return s; } void main() { int num,a[10]={1,2,3,4,5,6,7,8,9,10}; int *p=a; scanf("%d",&num); printf("%d\n",sum(p,num)); } 编程题:指针变量,实参与形参的引用.已知

编程题:已知一个一维数组,求其中前n个数的和。n由键盘输入

#include<stdio.h> int sum(int array[],int n) { int i,s=0; for(i=0;i<n;i++) s+=array[i]; return s; } void main() { int num,a[10]={1,2,3,4,5,6,7,8,9,10}; scanf("%d",&num); printf("%d\n",sum(a,num)); } 编程题:已知一个一维数组,求其中前n个数的和.

已知一个数组,将所有元素乘二存储到原数组

/** * */package Student_System;import java.util.*;/**Homework11 * *ArrayDemo05 * 已知一个数组,将所有元素乘二存储到原数组 * @author 读你一世* * QQ: 1816274408 *2017年4月13日下午10:05:22 * */public class ArrayDemo05 { public static void main(String[] args){// 确定数组元素,便于赋值 Scanner

例6.13 已知一个一维数组a[1..n](n&lt;25),又已知一整数m。 如能使数组a中任意几个

/*例6.13 已知一个一维数组a1..n,又已知一整数m. 如能使数组a中任意几个元素之和等于m,则输出YES,反之则为NO.[分析]对于一个已确定的数组a[1..n]和一个确定的数m,判断能否使数组a中任意几个元素之和等于m,等价于判断能否从数组a中取任意数使其和为m. 对于a中任意元素a[n]只有取与不取两种情况: (1)取a[n]: 则此时问题转化为:对于一个已确定的数组a[1..n-1]和一个确定的数m-a[n],判断能否使数组a[1..n-1]中任意几个元素之和等于m-a[n]. (

已知一个函数rand5()能够生成1-5的随机数,请给出一个函数,该函数能够生成1-7的随机数。

这是朋友去笔试的一道题,有点考智商,当时我还很自信的说 random5+random5/2  不就可以了 他说不行,然后我就在网上搜了一下 有一道类似的题目 题目: 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数,该函数能够生成1-10的随机数. 思路: 假如已知一个函数能够生成1-49的随机数,那么如何以此生成1-10的随机数呢? 解法: 该解法基于一种叫做拒绝采样的方法.主要思想是只要产生一个目标范围内的随机数,则直接返回.如果产生的随机数不在目标范围内,则丢弃该值,重新取

在平面内,已知一个矩形的四个角坐标,将矩形绕中心点转动一个角度,求旋转后的角坐标.

在平面内,已知一个矩形的四个角坐标,将矩形绕中心点转动一个角度,求旋转后的角坐标.也就是已知半径,求每个点旋转后的坐标. 把旋转前和旋转后的点加上中心点看成一个等腰三角形就好解决了,不用扇形公式,而是用三角形公式.假设矩形的左上角为(left, top),右下角为(right, bottom),则矩形上任意点(x0, y0)绕其中心(xcenter,ycenter)逆时针旋转angle角度后,新的坐标位置(x′, y′)的计算公式为: xcenter = (right - left + 1) /

select * from 后有多个表的使用方法(已知一个表的结构为xxx 怎样通过select语句把他变成以下结构)

已知一个表的结构为: 怎样通过select语句把他变成以下结构: 首先,添加数据 USE [DBTEST]GO/****** Object: Table [dbo].[SDUDENTS] Script Date: 2019/12/9 10:33:41 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[SDUDENTS]( [GUID] [int] IDENTITY(100001,1) NOT NULL,