剑指offer——其一

如何从已排好序的二维数组中寻找某数

private static boolean findnum(int num, int[][] arr) {
	// TODO Auto-generated method stub
	int i,j=0;
	int r=arr.length,c=arr[0].length;
	if(r==0) return false;
	if(c==0) return false;
	for(i=0;i<r;i++) {
		if(num>=arr[i][0]&&num<=arr[i][c-1]) {
			for(j=0;j<c;j++) {
				if(num==arr[i][j])
					return true;
			}
		}
	}
	return false;
}

思路:比较每行最大值和最小值,从而排除一整行.

替换字符串中的某种字符

直接调用java自带函数str.replace(src,des);或用stringbuilder存储,遇上src就添加des

已知前序遍历和中序遍历,求该二叉树

/*public class TreeNode {
*     int val;
*     TreeNode left;
*     TreeNode right;
*     TreeNode(int x) { val = x; }
* }
*/
import java.util.Arrays;
public class Solution {

public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
    if(pre.length == 0||in.length == 0)
      return null;
  	TreeNode root=new TreeNode(pre[0]);
  	for(int i=0;i<in.length;i++){
    	if(in[i]==pre[0]){
    	  root.left=reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
    	  root.right=reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
    	  break;
    	}
  	}
  return root;
  }
}

思路:从前序遍历中寻找根节点,用中序遍历确定左右子树,然后进行递归调用即可!(注意Arrays.copyOfRange()函数是左闭右开)

两个栈是这样成为队列的

思路:push()函数是一样的.而pop()则一个栈出一个栈进,就能将栈底元素调到栈顶.

import java.util.Stack;
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.size() <= 0) {
        while (stack1.size() != 0) {
            stack2.push(stack1.pop());
        }
    }
    return stack2.pop();
    }
}

Fibonacci玩出花

为了避免调用栈,可使用循环.

f(n+1)=f(n)+f(n-1)

当计算出f(n+1)时,sum=sum+one;此时sum存的是f(n+1)的值,而one存的是f(n-1)的值.所以,用one=sum-one使得one存储f(n)的值

class Solution {
public:
int Fibonacci(int n) {
if(n==0) return 0;
if(n==1) return 1;
    int sum= 1;
    int one = 0;
   for(i=2;i<=n;i++){
        sum+=one;
one=sum-one;
    }
    return sum;
}
};

同理小青蛙跳台阶也是此种解法!

变态跳台阶也是这样的,不过还能更直接,因为变态一次可以跳1个,2个...n个台阶,也就是f(n)=f(1)+f(2)+...+f(n-1)但是用数学归纳法,就可以清晰的得出,f(n)=2的(n-1)次方.用一个快速幂运算

public class Solution {
public int JumpFloorII(int n) {
  if(n==1) return 1;
  if(n==2) return 2;
  int a=n-1;
  int tmp=2;
  int res=1;
  while(a!=0){
    if((a&1)==1)
      res=res*tmp;
    tmp=tmp*tmp;
    a>>=1;
  }
  return res;
}
}

或者int res=1<<(n-1);计算的就是2的n-1次方

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

public int NumberOf1(int n) {
  int count=0;
  while(n!=0){
    count++;
    n&=(n-1);
  }
  return count;
}

那个n&=(n-1);是将最低位1变成0,是不是很神奇

快速幂运算

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

需要考虑exponent为负数的情况

public double Power(double base, int exponent) {
    if(exponent==0) return 1;
  if(exponent==1) return base;
  int flag=0;
  if(exponent<0)
  {flag=1;
   exponent=-exponent;}
  double pingfang=base;
  double res=1;
  while(exponent!=0){
    if((exponent&1)==1)
      res=res*pingfang;
    pingfang*=pingfang;
    exponent>>=1;
  }
  if(flag==1)
    return 1/res;
  return res;
}

顺时针打印二维数组

需要好好分析一下特殊情况

while循环里面的事情如下

	while(start<=row&&start<=col) {
		while(y<=col) {
			System.out.print(arr[x][y]+" ");
			y++;
		}y--;x++;
		while(x<=row) {
			System.out.print(arr[x][y]+" ");
			//System.out.println(x+" "+y);
			x++;
		}x--;y--;
		while(y>=start&&x>start) {
			System.out.print(arr[x][y]+" ");
			//System.out.println(x+" "+y);
			y--;
		}y++;x--;
		while(x>start&&y>=start&&y!=col) {
			System.out.print(arr[x][y]+" ");
			x--;
		}start++;
		x=y=start;
		row--;col--;
	}

最小栈

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数,时间复杂度应为O(1).

 Stack<Integer> Q=new Stack<Integer>();
 Stack<Integer> Min=new Stack<Integer>();
public void push(int node) {
  if(Q.isEmpty()||(node < Min.peek())){
    Min.push(node);
  }else{
    Min.push(Min.peek());
  }
  Q.push(node);
}

public void pop() {
    Q.pop();
  Min.pop();
}

public int top() {
    return Q.peek();
}

public int min() {
    return Min.peek();
}

思路:应用双栈思想,存储每一种状态的最小值
或者直接构造新型数据结构,如

struct Node{
int val;
int min;};

输入两个整数序列,判断这两个整数序列顺序是否一致

public boolean IsPopOrder(int [] pushA,int [] popA) {
  Stack<Integer> Q=new Stack<Integer>();
  int i=0,j=0;
  Q.push(pushA[i]);
  i++;
  if(Q.isEmpty()) return false;
  while(i<pushA.length||j<pushA.length){
    if(Q.peek()==popA[j]){
      Q.pop();
      j++;
    }else{
      if(i==pushA.length)
        return false;
      Q.push(pushA[i]);
        i++;
    }
   
  }
  if(Q.isEmpty()) return true;
  else return false;
  }
posted @ 2020-05-29 20:27  梅落南山  阅读(120)  评论(0编辑  收藏  举报