2.实现一个特殊栈,除了基本功能,还能返回栈中最小元素
解法:两个栈:stackData,stackMin
public static class MyStack1 {
private Stack<Integer> stackData;
private Stack<Integer> stackMin;
public MyStack1() {
this.stackData = new Stack<Integer>();
this.stackMin = new Stack<Integer>();
}
public void push(int newNum) {
if (this.stackMin.isEmpty()) {
this.stackMin.push(newNum);
} else if (newNum <= this.getmin()) {
this.stackMin.push(newNum);
}
this.stackData.push(newNum);
}
public int pop() {
if (this.stackData.isEmpty()) {
throw new RuntimeException("Your stack is empty.");
}
int value = this.stackData.pop();
if (value == this.getmin()) {
this.stackMin.pop();
}
return value;
}
public int getmin() {
if (this.stackMin.isEmpty()) {
throw new RuntimeException("Your stack is empty.");
}
return this.stackMin.peek();
}
}
3.1.用两个栈模拟一个队列
public static class TwoStacksQueue {
private Stack<Integer> stackPush;
private Stack<Integer> stackPop;
public TwoStacksQueue(){
this.stackPush=new Stack<>();
this.stackPop=new Stack<>();
}
public void push(int pushInt) {
this.stackPush.add(pushInt);
}
public int poll() {
if(this.stackPop.isEmpty()&&this.stackPush.isEmpty()){
throw new RuntimeException("队列为空");
}
dao();
return this.stackPop.pop();
}
public int peek() {
if(this.stackPop.isEmpty()&&this.stackPush.isEmpty()){
throw new RuntimeException("队列为空");
}
dao();
return this.stackPop.peek();
}
public void dao(){
if(this.stackPop.isEmpty()) {
while (!this.stackPush.isEmpty()) {
this.stackPop.push(this.stackPush.pop());
}
}
}
}
3.2.用两个队列模拟一个栈
public static class TwoQueuesStack {
private Queue<Integer> queue;
private Queue<Integer> help;
public TwoQueuesStack(){
this.queue=new LinkedList<>();
this.help=new LinkedList<>();
}
public void push(int pushInt) {
queue.add(pushInt);
}
public int peek() {
if(queue.isEmpty()){
throw new RuntimeException("该栈中无元素");
}
while(queue.size()!=1){
help.add(queue.poll());
}
int popInt=queue.peek();
help.add(queue.poll());
swap();
return popInt;
}
public int poll() {
if(queue.isEmpty()){
throw new RuntimeException("该栈中无元素");
}
while(queue.size()!=1){
help.add(queue.poll());
}
int popInt=queue.poll();
swap();
return popInt;
}
private void swap() {
Queue<Integer> temp=this.queue;
this.queue=this.help;
this.help=temp;
}
}
4.给定二维数组,从左上角到右下角,每一步只能向下或者向右,沿途经过的数累加,返回最小路径和
(1)递归版本
public static int getMinPath(int [][] arr){
return process(arr,0,0);
}
private static int process(int[][] arr, int i, int j) {
if(i==arr.length-1&&j==arr[0].length-1){
return arr[i][j];
}
if(i==arr.length-1){
return arr[i][j]+process(arr,i,j+1);
}
if(j==arr[0].length-1){
return arr[i][j]+process(arr,i+1,j);
}
return arr[i][j]+Math.min(process(arr,i,j+1),process(arr,i+1,j));
}
(2)dp
public static int getMinPathDP(int [][] arr){
int dp[][]=new int[arr.length][arr[0].length];
int row=arr.length-1;
int col=arr[0].length-1;
dp[row][col]=arr[row][col];
for(int i=row-1;i>=0;i--){
dp[i][col]=arr[i][col]+dp[i+1][col];
}
for(int j=col-1;j>=0;j--){
dp[row][j]=arr[row][j]+dp[row][j+1];
}
for(int i=row-1;i>=0;i--){
for(int j=col-1;j>=0;j--){
dp[i][j]=arr[i][j]+Math.min(dp[i][j+1],dp[i+1][j]);
}
}
return dp[0][0];
}
5.给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个容器,请返回容器能装多少水
输入:[3,1,2,5,2,4] 输出:5
public static int getWater5(int[] arr){
if(arr==null||arr.length<3){
return 0;
}
int all=0;//总的多少水
int l=1;
int r=arr.length-2;
int maxl=arr[0];
int maxr=arr[arr.length-1];
while (l<=r){
if(maxr<=maxl){
all+=(maxr-arr[r])>0?(maxr-arr[r]):0;
maxr=(maxr-arr[r])>0?maxr:arr[r];
r--;
}else{
all+=(maxl-arr[l])>0?(maxl-arr[l]):0;
maxl=(maxl-arr[l])>0?maxl:arr[l];
l++;
}
}
return all;
}
(1)暴力,到每一个位置的时候求出左边的最大值与右边的最大值
public static int max(int[] arr){
int max=Integer.MIN_VALUE;
int len=arr.length;
for(int i=0;i<=len-2;i++){
int maxLeft=Integer.MIN_VALUE;
for(int j=0;j<=i;j++){
if(arr[j]>=maxLeft){
maxLeft=arr[j];
}
}
int maxRight=Integer.MIN_VALUE;
for(int m=i+1;m<=len-1;m++){
if(arr[m]>=maxRight){
maxRight=arr[m];
}
}
max=Math.max(Math.abs(maxLeft-maxRight),max);
}
return max;
}
(2)预处理数组:预先求出每个位置左边的最大值与右边的最大值
public static int maxPreTreat(int[] arr){
int len=arr.length;
int [] left=new int[len];
int maxLeft=Integer.MIN_VALUE;
for(int i=0;i<=len-1;i++){
if(i==0){
left[i]=arr[i];
maxLeft=arr[0];
}else {
left[i]=Math.max(maxLeft,arr[i]);
}
}
int [] right=new int[len];
int maxRight=Integer.MIN_VALUE;
for(int i=len-1;i>=0;i--){
if(i==len-1){
right[i]=-1;
}else{
right[i]=maxRight=Math.max(maxRight,arr[i+1]);
}
}
int max=Integer.MIN_VALUE;
for(int i=0;i<=len-2;i++){
max=Math.max(Math.abs(left[i]-right[i]),max);
}
return max;
}
(3)最优化解法:求出数组最大值,两种情况:max在左侧和右侧
public static int maxSimple(int[] arr){
int max=Integer.MIN_VALUE;
for(int i=0;i<arr.length;i++){
max=Math.max(max,arr[i]);
}
int num=Math.max(Math.abs(max-arr[0]),Math.abs(max-arr[arr.length-1]));
return num;
}
7.题目:
如果一个字符串str,把字符串str前面任意的部分挪到后面形成的字符串叫做str的旋转词。
如str=“12345”,str的旋转词有"12345"、“23451”、“34512”、“45123”、“51234”。
给定两个字符串a和b,请判断a和b是否互为旋转词。
举例:
a=“cdab”,b=“abcd”,返回true;
a=“1ab2”,b=“ab12”,返回false;
a=“2ab1”,b=“ab12”,返回true。
public static boolean isRotation1(String a, String b) {
if (a==null||b==null||a.length()!=b.length()){
return false;
}
String num=a+a;
int is = num.indexOf(b);
return is==-1?false:true;
}