《剑指offer》-- 构建乘积数组、求1+2+3+...+n、不用加减乘除做加法、包含min函数的栈、用两个栈实现队列
一、构建乘积数组:
1、题目:
给定一个数组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]。不能使用除法。
2、解题思路:
参考牛客网的“披萨大叔”:https://www.nowcoder.com/questionTerminal/94a4d381a68b47b7a8bed86f2975db46
B[i]的值可以看作下图的矩阵中每行的乘积。
下三角用连乘可以很容求得,上三角,从下向上也是连乘。
因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去。
3、代码实现:
public class Test7 {public int[] multiply(int[] A) {int length= A.length;int[] B = new int[length];if(length!=0){B[0]=1;//计算下三角连乘for(int i = 1;i<length;i++){B[i]=B[i-1]*A[i-1];}int temp=1;//计算上三角连乘for(int j=length-2;j>=0;j--){temp=temp*A[j+1];B[j]=B[j]*temp;}}return B;}
}
二、求1+2+3+...+n
1、题目:
1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
2、解题思路:
利用&&的短路特性,&&就是逻辑与,逻辑与有个短路特点,前面为假,后面不计算。
3、代码实现:
public class Solution {public int Sum_Solution(int n) {//利用&&的短路特性,&&就是逻辑与,逻辑与有个短路特点,前面为假,后面不计算。boolean result=true;int sum =0;result=(n>0) && ((sum=Sum_Solution(n-1))>0);sum=sum+n;return sum;}
}
三、不用加减乘除做加法:
1、题目:
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
2、解题思路:
首先看十进制是如何做的: 5+7=12,三步走:
第一步:相加各位的值,不算进位,得到2。
第二步:计算进位值,得到10. 如果这一步的进位值为0,那么第一步得到的值就是最终结果。
第三步:重复上述两步,只是相加的值变成上述两步的得到的结果2和10,得到12。
同样我们可以用三步走的方式计算二进制值相加: 5-101,7-111 第一步:相加各位的值,不算进位,得到010,二进制每位相加就相当于各位做异或操作,101^111。
第二步:计算进位值,得到1010,相当于各位做与操作得到101,再向左移一位得到1010,(101&111)<<1。
第三步重复上述两步, 各位相加 010^1010=1000,进位值为100=(010&1010)<<1。
继续重复上述两步:1000^100 = 1100,进位值为0,跳出循环,1100为最终结果。
3、代码实现:
public class Test25 {public int Add(int num1,int num2) {while(num2!=0){int temp=num1^num2;num2=(num1&num2)<<1;num1 = temp;}return num1;}
}
四、包含min函数的栈:
1、题目:
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
2、第一种解题思路:
借助辅助栈存储min的大小,自定义栈结构
list 3,4,2,5,1
辅助栈 3,3,2,2,1
每入栈一次,就与辅助栈顶比较大小,如果小就入栈,如果大就入栈当前的辅助栈的栈顶元素;
当出栈时,辅助栈也要出栈,这种做法可以保证辅助栈顶一定都当前栈的最小值
代码实现:
public class Test7 {private int size;//数组容量private int min=Integer.MAX_VALUE;//最小元素private Stack<Integer> minStack = new Stack<Integer>();//辅助栈private Integer[] elements = new Integer[10];//数据入栈,每入栈一次,就与辅助栈顶比较大小,如果小就入栈,如果大就入栈当前的辅助栈的栈顶元素。public void push(int node){ensureCapacity(size+1);elements[size++]= node;if(node<=min){minStack.push(node);min=minStack.peek();}else{minStack.push(min);}}//数组扩容private void ensureCapacity(int i) {int len=elements.length;if(size>len){int newLen =(len*3)/2+1;//每次扩容的方式elements=Arrays.copyOf(elements, newLen);}}//元素出栈,当出栈时,辅助栈也要出栈,保证辅助栈顶一定都当前栈的最小值private void pop(){Integer top=top();if(top!=null){elements[size-1] =(Integer)null;}size--;minStack.pop();min=minStack.peek();}public int top(){if(!empty()){if(size-1>=0){return elements[size-1];}}return (Integer)null;}public boolean empty(){return size == 0;}public int min(){return min;}
}
3、第二种解题思路:
每次入栈2个元素,一个是入栈的元素本身,一个是当前栈元素的最小值。 如:入栈序列为2-3-1,则入栈后栈中元素序列为:2-2-3-2-1-1 * 用空间代价来换取时间代价:
代码实现:
import java.util.Stack;
import java.util.Arrays;public class Solution {private Stack<Integer> stack = new Stack<Integer>();public void push(int node) {if(stack.isEmpty()){stack.push(node);stack.push(node);}else{int temp = stack.peek();stack.push(node);if(temp<node){stack.push(temp);}else{stack.push(node);}}}public void pop() {stack.pop();stack.pop();}public int top() {return stack.get(stack.size()-2);}public int min() {return stack.peek();}
}
五、用两个栈实现队列:
1、题目描述:
两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
2、思路分析:
入队:将元素进栈A
出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;如果不为空,栈B直接出栈。
3、代码实现:
public class Solution{Stack<Integer> stack1 = new Stack<Integer>();Stack<Integer> stack2 = new Stack<Integer>();public void push(int node) {stack1.push(node);}public int pop() {if(stack2.isEmpty()){while(!stack1.isEmpty()){stack2.push(stack1.pop());}}return stack2.pop();}
}
《剑指offer》-- 构建乘积数组、求1+2+3+...+n、不用加减乘除做加法、包含min函数的栈、用两个栈实现队列相关推荐
- 剑指Offer66—构建乘积数组
剑指Offer66 题意 法1-暴力法(无法通过) class Solution { public:vector<int> constructArr(vector<int>&a ...
- 剑指offer51 构建乘积数组(图解)
描述 给定一个数组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].不能使 ...
- 剑指offer不用加减乘除做加法_剑指Offer-不用加减乘除做加法
题目描述 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 思路 思路一: 位运算 思路二: 递归 思路三: 调用Integer的sum方法 思路四: 自增自减 代码实现 ...
- 【剑指offer】数据结构——数组
目录 数据结构--数组 直接解 [剑指offer]03.数组中重复的数字 排序法 集合法 原地置换 [剑指offer]04. 二维数组中的查找 [剑指offer]29. 顺时针打印矩阵 [剑指offe ...
- 《LeetCode力扣练习》剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 Java
<LeetCode力扣练习>剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 Java 一.资源 题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组 ...
- 《LeetCode力扣练习》剑指 Offer 11. 旋转数组的最小数字 Java
<LeetCode力扣练习>剑指 Offer 11. 旋转数组的最小数字 Java 一.资源 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 给你一个可能存在 ...
- 剑指 Offer 11. 旋转数组的最小数字 简单
剑指 Offer 11. 旋转数组的最小数字 题目 解题思路 方法(一)直接遍历法 方法(二)二分查找法 题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组 ...
- 剑指offer 11. 旋转数组的最小数字(很详细!)
剑指offer 11. 旋转数组的最小数字 题目 解题思路 代码 题目 解题思路 一开始,我们就能直接想到,数组找最小值,那么不轻轻松松直接遍历一遍,用一个变量记录最小值,然后直接返回不就完事了? 但 ...
- 【LeetCode】剑指 Offer 45. 把数组排成最小的数
[LeetCode]剑指 Offer 45. 把数组排成最小的数 文章目录 [LeetCode]剑指 Offer 45. 把数组排成最小的数 package offer;import java.uti ...
最新文章
- 改变自己,让自己变得更好
- 复习下mybatis 中 useGeneratedKeys 和 keyProperty 含义
- 社会化工程攻击针对目标不再仅限最终用户
- 使用 CoreDNS sidecar 来优化 Kubernetes Pod dns 性能
- wordpress拒绝访问_Nginx + Wordpress页面或帖子URL返回拒绝访问
- U盘文件系统无法识别,数据怎么恢复?
- python创建一个csv文件_python操作csv文件
- 【论文写作】招聘系统总体流程图如何画
- Android下的串口通信实战之电子秤交互
- 主流四大虚拟化架构对比分析
- 英语句式参考纯享版 - 主语从句 - 表语从句
- html设计思路,网页设计思路7个方法
- R语言学习笔记:使用reshape2包实现整合与重构
- Java 视频转换h265、h264、mkv、mp4
- DS18B20温度转换与显示
- 七大原则+23种设计模式
- 4G--水控机物联网版本多个出水口---完善中
- vba 用adodb连接mysql_【VBA研究】Excel VBA利用ADODB访问数据库使用小结
- 王坚,一个革新者的故事
- 关于tlq的一些命令
热门文章
- 三十三、深入Python中的itertools模块
- 一、史上最强hadoop分布式集群的搭建
- selenium容易忽视的知识点
- 通过pycharm启动django
- 4g能用吗64java_java – 用于4G内存的JBoss 7内存配置,64位
- 直播 | AAAI 2022论文解读:三⻆分解一致性约束的端到端语音翻译
- 知识图谱领域有哪些最新研究进展?不妨从EMNLP 2021录用论文寻找答案
- 今日arXiv精选 | 31篇EMNLP 2021最新论文
- 被“轻视”的CV·AR的背后核心技术
- 让你的文字被很多很多人看到,喜欢我们不如加入我们 | 作者招募