一、构建乘积数组:

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函数的栈、用两个栈实现队列相关推荐

  1. 剑指Offer66—构建乘积数组

    剑指Offer66 题意 法1-暴力法(无法通过) class Solution { public:vector<int> constructArr(vector<int>&a ...

  2. 剑指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].不能使 ...

  3. 剑指offer不用加减乘除做加法_剑指Offer-不用加减乘除做加法

    题目描述 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 思路 思路一: 位运算 思路二: 递归 思路三: 调用Integer的sum方法 思路四: 自增自减 代码实现 ...

  4. 【剑指offer】数据结构——数组

    目录 数据结构--数组 直接解 [剑指offer]03.数组中重复的数字 排序法 集合法 原地置换 [剑指offer]04. 二维数组中的查找 [剑指offer]29. 顺时针打印矩阵 [剑指offe ...

  5. 《LeetCode力扣练习》剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 Java

    <LeetCode力扣练习>剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 Java 一.资源 题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组 ...

  6. 《LeetCode力扣练习》剑指 Offer 11. 旋转数组的最小数字 Java

    <LeetCode力扣练习>剑指 Offer 11. 旋转数组的最小数字 Java 一.资源 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 给你一个可能存在 ...

  7. 剑指 Offer 11. 旋转数组的最小数字 简单

    剑指 Offer 11. 旋转数组的最小数字 题目 解题思路 方法(一)直接遍历法 方法(二)二分查找法 题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组 ...

  8. 剑指offer 11. 旋转数组的最小数字(很详细!)

    剑指offer 11. 旋转数组的最小数字 题目 解题思路 代码 题目 解题思路 一开始,我们就能直接想到,数组找最小值,那么不轻轻松松直接遍历一遍,用一个变量记录最小值,然后直接返回不就完事了? 但 ...

  9. 【LeetCode】剑指 Offer 45. 把数组排成最小的数

    [LeetCode]剑指 Offer 45. 把数组排成最小的数 文章目录 [LeetCode]剑指 Offer 45. 把数组排成最小的数 package offer;import java.uti ...

最新文章

  1. 改变自己,让自己变得更好
  2. 复习下mybatis 中 useGeneratedKeys 和 keyProperty 含义
  3. 社会化工程攻击针对目标不再仅限最终用户
  4. 使用 CoreDNS sidecar 来优化 Kubernetes Pod dns 性能
  5. wordpress拒绝访问_Nginx + Wordpress页面或帖子URL返回拒绝访问
  6. U盘文件系统无法识别,数据怎么恢复?
  7. python创建一个csv文件_python操作csv文件
  8. 【论文写作】招聘系统总体流程图如何画
  9. Android下的串口通信实战之电子秤交互
  10. 主流四大虚拟化架构对比分析
  11. 英语句式参考纯享版 - 主语从句 - 表语从句
  12. html设计思路,网页设计思路7个方法
  13. R语言学习笔记:使用reshape2包实现整合与重构
  14. Java 视频转换h265、h264、mkv、mp4
  15. DS18B20温度转换与显示
  16. 七大原则+23种设计模式
  17. 4G--水控机物联网版本多个出水口---完善中
  18. vba 用adodb连接mysql_【VBA研究】Excel VBA利用ADODB访问数据库使用小结
  19. 王坚,一个革新者的故事
  20. 关于tlq的一些命令

热门文章

  1. 三十三、深入Python中的itertools模块
  2. 一、史上最强hadoop分布式集群的搭建
  3. selenium容易忽视的知识点
  4. 通过pycharm启动django
  5. 4g能用吗64java_java – 用于4G内存的JBoss 7内存配置,64位
  6. 直播 | AAAI 2022论文解读:三⻆分解一致性约束的端到端语音翻译
  7. 知识图谱领域有哪些最新研究进展?不妨从EMNLP 2021录用论文寻找答案
  8. 今日arXiv精选 | 31篇EMNLP 2021最新论文
  9. 被“轻视”的CV·AR的背后核心技术
  10. 让你的文字被很多很多人看到,喜欢我们不如加入我们 | 作者招募