《剑指offer》-数组乘积,不使用除法

题目描述
给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]A[1]...A[i-1]A[i+1]...A[n-1]。不能使用除法。

这题不准用除法,那么就转化。首先想到的是用“先取log再e回去”的做法,但是因为坑比较多,比如A[i]等于0的情况,log处理0不好弄。

但是这种思路并非一无是处。当发现log 0做不下去,就容易想到直接元素A[i]左右两侧各个元素的乘积left和right,它俩的乘积left x right就是最终的结果啊。

那么结果数组的每个元素B[i]就分解成左右两部分的乘积。代码就是网上找到的通用版本那个了。复杂度O(n^2)

class Solution {
public:
    vector<int> multiply(const vector<int>& A) {
        vector<int> B(A.size());

        vector<int> left(A.size());
        left[0] = 1;

        cout << "left:" << endl;
        for (int i = 1; i<A.size(); i++){
            left[i] = left[i - 1] * A[i-1];
        }
        for (int i = 0; i < A.size(); i++){
            cout << left[i] << " ";
        }
        cout << endl;

        cout << "right:" << endl;
        vector<int> right(A.size());
        right[A.size()-1] = 1;
        for (int i = A.size()-2; i>=0; i--){
            right[i] = right[i + 1] * A[i+1];
            //cout << right[i] << " ";
        }
        for (int i = 0; i < A.size(); i++){
            cout << right[i] << " ";
        }
        cout << endl;

        for (int i = 0; i<B.size(); i++){
            B[i] = left[i] * right[i];
        }
        return B;
    }
};
时间: 2024-09-30 14:09:26

《剑指offer》-数组乘积,不使用除法的相关文章

[剑指Offer]5.二维数组中的查找

题目 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路 [算法系列之三十三]杨氏矩阵 代码 /*--------------------------------------- * 日期:2015-07-19 * 作者:SJF0115 * 题目: 5.二维数组中的查找 * 网址:http://www.nowcoder.com/books/coding-interviews/a

[剑指Offer]40.数组中只出现一次的数字

题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路 我们直到异或的性质: 任何一个数字异或他自己都等于0. 所以说我们如果从头到尾依次异或每一个数字,那么最终的结果刚好只出现一次的数字,因为成对出现的两次的数字全部在异或中抵消了. 这道题中有两个数字只出现一次.这样的话我们得到的结果就是这两个数字的异或结果.因此我们想办法把原数组分成两个子数组,使得每个子数组包含一个只出现一次的数字.这样我们就可以对这两个子数组分别异或,就能得到两个只出现一

剑指offer系列之十二:调整数组顺序使奇数位于偶数前面

题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 这道题第一思路自然是这样的:从头开始遍历这个数组,如果遇到偶数就把这个数之后的所有数往前移动一位,这样数组会留出一个空位,移动完毕之后把该偶数放到该空位即可.这样处理的话需要两次循环,一次是遍历,另一次是移位,所以时间复杂度是O(n2).下面是这种思路的实现代码(已被牛客AC): public void reOrd

剑指offer系列之三:在二维数组中查找元素

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 由于题目条件的成立,所以使得这道题可以使用对角线的方法完成,可以从右上角的元素考虑,如果目标查找元素小于右上角的元素,那么不可能在右上角元素所在的列,如果目标大于剩余列的右上角的元素,那么不可能在该右上角元素所在的行.依照这个规律,就可以完成目标元素的查找(参考剑指offer书中的思路).基于此,我写出如下的代码(已被

[剑指Offer]10.旋转数组的最小数字

题目1386:旋转数组的最小数字 题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数. 输入的第二行包括n个整数,其中每个整数a的范围是(1<=a<=10000000). 输出:

剑指Offer之调整数组顺序使奇数位于偶数前面

#include <stdio.h> #include <malloc.h> int *number; void SortOddBeforeEven(int *number,int n){ int left = 0,right = n-1; //下标 int oIndex = 0,eIndex = 0; //二分遍历 while(left < right){ //从左边直到第一个偶数 while(left < right && (number[left]

剑指offer之和为定值的两个数

题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输入: 每个测试案例包括两行: 第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和.其中1 <= n <= 10^6,k为int 第二行包含n个整数,每个数组均为int类型. 输出: 对应每个测试案例,输出两个数,小的先输出.如果找不到,则输出"-1 -1" 样例输入: 6 15 1 2 4 7 11 15 样例输出:

剑指Offer之和为S的两个数字

题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输入: 每个测试案例包括两行: 第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和.其中1 <= n <= 10^6,k为int 第二行包含n个整数,每个数组均为int类型. 输出: 对应每个测试案例,输出两个数,小的先输出.如果找不到,则输出"-1 -1" 样例输入: 6 15 1 2 4 7 11 15 样例输出:

剑指offer:包含min函数的栈

剑指offer上的第21题,之前在Cracking the Coding interview上做过,思路参考这里,这次写了测试函数,在九度OJ上测试通过. 题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行为一个整数n(1<=n<=1000000), n代表将要输入的操作的步骤数. 接下来有n行,每行开始有一个字母Ci. Ci='s'时,接下有一个数字k,代表将k压入栈. Ci

剑指offer:栈的压入弹出序列

剑指offer上的第22题,九度OJ上AC. 题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列. 输入: 每个测试案例包括3行: 第一行为1个整数n(1<=n<=100000),表示序列的长度. 第二行包含n个整数,表示栈的压入顺序. 第三行包含n个整数,表示栈的弹出顺序