1. 程式人生 > >劍指offer(java程式碼版)

劍指offer(java程式碼版)

1,singleTon例項 題目描述:設計一個類,我們只能生成該類的一個例項 //volatile:防止指令重排序 public class singletonClass{

private static volitile singletonClass instance;

private singletonClass(){

}

public static singletonClass getInstance(){

if(instance==null){
   synchronized(singletonClass.class){
      if(instance==null){
      instance = new singletonClass();
} 
}   
return instance;

} } }

2,二位陣列中的查詢 在一個二位陣列中,每一行都按照從左到右遞增的順序排列,每一列都按照從上到下的順序排序,完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否包含該整數

public class find(){

public static boolean find(int arr[][],int keyNumber){

 int column =arr[0].length-1;
 int row = 0;
 while(column>0&&row<arr.length){
   if(arr[row][column]==keyNumber){
       return true;
   }  
  else if(arr[arr][column]>keyNumber){
      column--;
   } 
  else{
     row++;
   }         
 }

} return false; } //測試find函式 public static void main(String args[]){ //測試這個陣列 /* * 1 2 8 9 * 2 4 9 12 * 4 7 10 13 * 6 8 11 15 */ int array[][] = new int[4][4]; array[0][0]=1; array[0][1]=2; array[0][2]=8; array[0][3]=9; array[1][0]=2; array[1][1]=4; array[1][2]=9; array[1][3]=12; array[2][0]=4; array[2][1]=7; array[2][2]=10; array[2][3]=13; array[3][0]=6; array[3][1]=8; array[3][2]=11; array[3][3]=15; System.out.println(find(array,7)); System.out.println(find(array,5)); }

3,空格替換 題目描述: 請實現一個函式,將字串的每個空格替換為"%20"。 例如輸入"We are happy",則輸出"We%20are%20happy."。

public class replaceBlank{

public String replace(String input){

StringBuilder build = new StringBuilder();
if(input==null||input.length()==0){
  return null;
}
for(int i=0;i<input.length();i++){
  
   if(input.charAt(i)==' '){
     builder.append("%");
     builder.append("2");
     builder.append("0");
   }else{
    builder.append(input.charAt(i));
   }
}
return builder.toString(); 

} }

//測試用例 public static void main(String[] args){ ReplaceBlank test = new ReplaceBlank();

String str1=“We are happy” System.out.println(test.replace(str1));

}

4,從尾到頭列印連結串列 題目描述:輸入一個連結串列的頭結點,從頭到尾反過來列印每個結點的值

//首先定義連結串列結構 class LinkNode{ LinkNode next; int node_value; }

public class PrintListReverse{ public void reverse(LinkNode headNode){ //用棧的思想來實現連結串列的倒敘輸出 Stack stack = new Stack(); while(headNode!=null){ stack.push(headNode); headNode = headNode.next; } while(!stack.isEmpty()){ System.out.println(stack.pop().node_value+""); } System.out.print(); }

public static void main(String[] args){

PrintListReverse plr = new PrintReverse(); LinkNode node1 = new LinkNode(); LinkNode node2 = new LinkNode(); LinkNode node3 = new LinkNode();

node1.next_value=1; node2.next_value=2; node3.next_value=3;

node1.next=node2; node2.next=node3; plr.reverse(node1); }

}

4,題目描述:輸入某二叉樹的前序遍歷和中序遍歷結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不包含重複的數字。例如輸入前序遍歷序列:{1,2,4,7,3,5,6,8}和中序遍歷{4,7,2,1,5,3,8,6},則重建出圖中所示二叉樹並且輸出它的頭結點。

重建的二叉樹:

//定義二叉樹節點 class BinaryTreeNode{ public int value; public BinaryTreeNode leftNode; public BinaryTreeNode rightNode;

//無參建構函式 public BinaryTreeNode{

}

//定義有參的建構函式 public BinaryTreeNode(int value){ this.value = value; this.leftNode = null; this.rightNode = null; } }

//構造二叉樹 public Class ConstructBinaryTree{

public static BinaryTreeNode construct(int preOrder{},int inOrder{},int length) throws Exception{
   
  if(preOrder ==null||inOrder==null||length<0){
    return null;
  }
  return constructCore(preOrder,0,preOrder.length-1,inOrder,0,inOrder.length - 1);      
}

public static BinaryTreeNode constructCore(int preOrder{},
int startPreIndex, int endPreIndex, int inOrder{},
int startInIndex,int endInIndex)throws InvalidPutException{

//頭結點的值
int rootValue = preOrder[startInIndex];

//構建一個只有一個根節點的二叉樹
BinaryTreeNode root  = new BinaryTreeNode(rootValue);

//只有一個元素的情況下
if(startPreIndex == endPreIndex){
   if(startInIndex == endInIndex
    && preOrder[startInIndex] == inOrder[endInIndex]){
     System.out.println("只有一個元素");
     return root;
    }else{
      throw new InvalidPutException();
    }
 }

//最重要的一步:在中序遍歷中找到根結點的索引
int rootInIndex = startInIndex;
while(rootInIndex<=endInIndex && inOrder[rootInIndex]!=rootValue){
     rootInIndex++;
}
if(rootInIndex == endInIndex && inOrder[rootInIndex]!=rootValue){
   throw new InvalidPutException();
}

//根結點的左子數的長度
int leftLength = rootInIndex - startInIndex;
//根節點的左子數的最右端的索引值
int leftPreEndIndex = startPreIndex + leftLength;    
//構建左子樹
if(leftLength>0){
 root.leftNode = constructCore(preOrder,startPreIndex + 1,
    leftPreEndIndex, inOrder,startInIndex,rootInIndex - 1);
}
//說明根結點存在右子數
if(leftLength < endPreIndex - startPreIndex){
   root.rightNode = constructCore(preOrder,leftPreEndIndex+1,
   endPreIndex,inOrder,rootInIndex+1,endInIndex);
}     
return root;

}

//按照前序遍歷列印二叉樹的節點 public static void printPreBinaryTree(BinaryTreeNode root){ if(root ==null){ return; }else{ System.out.println(root.value+""); }

if(root.leftNode!=null){
 printPreBinaryTree(root.rightNode);
}
if(root.rightNode!=null){
 printPreBinaryTree(root.rightNode);
}

}

public static class InvalidPutException extends Exception {

      private static final long serialVersionUID = 1L;
}

public static void main(String[] args) throws Exception{ int preOrder[] = {1,2,4,7,3,5,6,8}; int inOrder[] = {4,7,2,1,5,3,8,6}; ConstructBinaryTree test = new ConstructBinaryTree(); printPreBinaryTree(test.construct(preOrder,inOrder,preOrder.length)); }

}

6,用兩個棧實現佇列 題目描述:用兩個棧實現一個佇列。佇列的宣告如下,請實現它的兩個函式appendTail和deleteHead,分別完成在佇列尾部插入結點和在佇列頭部刪除結點的功能。

public class constractQueue{

Stack stack1 = new Stack(); Stack stack2 = new Stack();

public void appendTail(int a){ stack1.push(a); }

public void deleteHead() Throws Exception{ if(stack2.isEmpty){ if(!stack1.isEmpty){ stack2.push(stack1.pop()); } } if(stack2.isEmpty){ System.out.println(“佇列為空不能刪除”); } return stack2.pop(); }

public static void main(String args[]){

ConstractQueue test = new ConstractQueue(); //向空的佇列中新增元素,刪除元素 test.append(“1”); System.out.println(test.deleteHead()); } }

7,旋轉陣列的最小數字 題目描述:把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入一個遞增排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1; public class MinInReversingList{

public static int minElement(int array[]) throws Exception{

   //條判斷
  if(array==null||array.length<=0){
    throw new Exception(Invalid parameters);
   }

  int left = 0;
  int right = array.length-1;
  int mid = left;
  while(array[left]>=array[right]){
    //跳出迴圈的條件
    if(right-left==1){
     mid = right;
     break;
     }
     mid = (left + right)/2;
     if(array[left]==array[mid] && array[mid] == array[right]){
         return minFromSortSearch(array);
      }else{
         //演算法的核心思想
        if(array[mid]>array[left]){
          left = mid;
        }
        if(array[mid]<=array[right]){
         right = mid
        }
      }            
  }
   return array[right];

} } 8,斐波那契數列 題目描述:寫一個函式,輸入n,求斐波那契數列的第n項,斐波那契數列的定義如下: n=0,f(n)=0 ;n=1,f(n)=1 n>1;f(n)=f(n-1)+f(n-2). 青蛙跳臺階的問題,也可以用裴波那契數列 package Fibonacci;

public class Fibonacci {

 public static long Fib2(int n) {
	       long FibOne = 0;
	       long FibTwo = 1;
	       long FibN = 0;
	       int result[] = { 0,1 };
	       if (n < 2) {
	           return result[n];
	       } else {
	           for (int i = 2; i <= n; i++) {
	               FibN = FibTwo + FibOne;
	               FibOne = FibTwo;
	               FibTwo = FibN;
	           }
	       }
	       return FibN;
	   }
	
	   public static void main(String[] args) {
	       // 用解法1求序列的第100項,直接不動了
	       // System.out.println(Fib1(100));
	       System.out.println(Fib2(2));
	   }

} 9,問題描述: 請實現一個函式,輸入一個整數,輸出該數二進位制表示中1的個數。例如把9表示成二進位制是1001,有2位是1 因此如果輸入9,該函式輸出2; public class NumbleOf1{

public int numble(int n ){ int count = 0; int flag = 1; while(flag!=0){ if((n&flag)!=0){ count++; } flag= flag<<1; } return count; }

public static void main(String args){ NumbleOf1 test = new NumbleOf1(); System.out.println(test.numble(9)); }

}

10,問題描述:實現函式double power(double base,int exponent),求base的exponent次方。不能使用庫函式,同時不需要考慮大數問題。

public class Power{

public double power(double base,int export){ double result = 0.0; if(equal(base,0)&& export0){ System.out.println(“0的負數次冪沒有意義”); } if(export0){ return result = 1.0; } if(export<0){ return unsignPower(base,-export); }else{ return unsignPower(base,export); } return result; }

public double unsignPower(double base,int export){ double result = 1.0; for(int i=0;i<export;i++){ result = result * base; } return result; }

//由於計算機有限的保留位數,因此當一個數與0相差0.000001時,預設為0, public boolean equal(double numble1,double numble2){ if((numble1 - numble2>-0.000001)&&(numble1 - numble2<0.000001)){ return ture; } return false; } }