劍指offer_牛客網_編程題_Java

目錄

 

二維數組中的查找

替換空格

從尾打印鏈表

重建二叉樹

用兩個棧實現隊列

旋轉數組的最小數字

斐波那契數列

跳臺階

變態跳臺階

矩形覆蓋

二進制中1的個數

數值的整數次方

調整數組順序使奇數位於偶數前面


 

二維數組中的查找

從右上角開始查找,如果小於target, 排除最後一列,如果大於target,排除第一行,然後取當前右上角如上述方法再次查找,直至右上角元素等於target,或者所有行和列都被淘汰。複雜度O(n) 。 T(2*n)

public class Solution {
    public boolean Find(int target, int [][] array) {
            //判斷array是否爲空需要進行三次判斷,當array=null 時,訪問array.length 非法
           if(array==null||array.length==0||(array.length==1&&array[0].length==0)) return false;
           int i = 0, j = array.length-1;
           while(i < array.length && j >= 0)
           {
               if(target == array[i][j]) return true;
               else if(target < array[i][j]) j--;
               else i++;
           }
        return false;
    }
}

替換空格

 

public class Solution {
    public String replaceSpace(StringBuffer str) {
    	StringBuffer ans = new StringBuffer();
        for(int i = 0; i < str.length(); i++)
            if(str.charAt(i) == ' ') ans.append("%20");
            else ans.append(str.charAt(i));
        return ans.toString();
    }
}
public class Solution {
    public String replaceSpace(StringBuffer str) {
    	return str.toString().replaceAll(" " , "%20");
    }
}

從尾打印鏈表

/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
    
    public void Dfs(ArrayList<Integer> ans,ListNode listNode)
    {
        if(listNode == null) return ;
        Dfs(ans,listNode.next);
        ans.add(listNode.val);
    }
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> ans = new ArrayList<>();
        Dfs(ans,listNode);
        return ans;
    }
}

重建二叉樹

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    
    public TreeNode Dfs(int l1, int r1, int l2, int r2, int[] pre, int[] in)
    {
        if(l1 > r1 || l2 > r2) return null;
        TreeNode root = new TreeNode(pre[l1]);
        int i;
        for(i = l2; i <= r2; i++)
            if(in[i] == pre[l1]) break;
        root.left = Dfs(l1+1,l1+i-l2, l2, i-1, pre, in);
        root.right = Dfs(l1+i-l2+1, r1, i+1, r2, pre, in);
        return root;
    }
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        return Dfs(0, pre.length-1, 0, in.length-1, pre, in);
    }
}

用兩個棧實現隊列

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        while(!stack2.empty()) stack1.push(stack2.pop());
        stack2.push(node);
        while(!stack1.empty()) stack2.push(stack1.pop());
    }
    
    public int pop() {
       return stack2.pop();
    }
}

旋轉數組的最小數字

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
     int temp = array[0],mina = array[0];
     for(int i = 1; i < array.length; i++)
         mina = Math.min(mina,array[i-1] = array[i]);
     array[array.length-1] = temp;
     return mina;
    }
}

斐波那契數列

public class Solution {
    public int Fibonacci(int n) {
        int[] f = {0,1,1};
        int i = 3;
        while(i <= n)
        {
            f[i%3] = f[(i-1)%3] + f[(i-2)%3];
            i++;
        }
        return f[n%3];
    }
}

跳臺階

public class Solution {
    public int JumpFloor(int target) {
         int[] f = {0,1,2};
         int i = 3;
        while(i <= target)
        {
            f[i%3] = f[(i-1)%3] + f[(i-2)%3];
            i++;
        }
        return f[target%3];
    }
}

變態跳臺階

public class Solution {
    public int JumpFloorII(int target) {
        int ans = 0;
        int sum = 0;
        while(target > 0)
        {
            ans = sum+1;
            sum += ans;
            target--;
        }
        return ans;
    }
}

矩形覆蓋

public class Solution {
    public int RectCover(int target) {
        int[] f = {0,1,2};
        int i = 3;
        while(i <= target)
        {
            f[i%3] = f[(i-1)%3] + f[(i-2)%3];
            i++;
        }
        return f[target%3];
    }
}

二進制中1的個數

public class Solution {
    public int NumberOf1(int n) {
        int res = 0;
        long m = n;
        if(n < 0) {
            m = (long)(Math.pow(2,32))+n;
        }
        while(m > 0) 
        {
            if((m & 1) == 1) res++;
            m >>= 1;
        }
        return res;
    }
}

數值的整數次方

採用快速冪比較快,不過要注意底數和指數爲負數的情況

public class Solution {
    
    double fpow(double x, int n)
    {
        double t = 1;
        if(x < 0) {x = -x; if((n&1) == 1) t = -1;}
        if(n == 0) return 1;
        double res = 1;
        boolean temp = true;
        if(n < 0) {temp = false; n = -n;}
        while(n > 0)
        {
            if((n & 1) == 1) res *= x;
            if(temp) x *= 2;
            else x /= 2;
            n >>= 1;
        }
        return res*t;
    }
    
    public double Power(double base, int exponent) {
        return fpow(base,exponent);
  }
}

調整數組順序使奇數位於偶數前面

先安利一個python 的一行代碼,真是強大。

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        return sorted(array,key = lambda c : c%2, reverse = True)

然後Java,有兩種做法,一種是犧牲空間換時間,再開一個數組來輔助求解,時間複雜度爲O(n), 另一種則是利用冒泡或者插入排序中交換的思想,來實現,時間複雜度O(n^2)。

方法一:

arraycopy 爲深度拷貝

public class Solution {
    public void reOrderArray(int [] array) {
       int[] temp = new int[array.length];
       int x = 0; 
       for(int i = 0; i < array.length; i++)
            if(array[i] % 2 == 1)temp[x++] = array[i];
       for(int i = 0; i < array.length; i++)
            if(array[i] % 2 == 0)temp[x++] = array[i];
      // for(int i = 0; i < array.length; i++)
      //      array[i] = temp[i];
       System.arraycopy(temp, 0, array, 0, temp.length);
    }
}

方法二:

用異或進行swap還是比較有意思的。

public class Solution {
    public void reOrderArray(int [] array) {
        for(int i = 0; i < array.length; i++)
        {
            if(array[i] % 2 == 1)
            for(int j = i-1; j >= 0; j--)
              if(array[j] % 2 == 0) 
              {
                  array[j] = array[j] ^ array[j+1];
                  array[j+1] = array[j] ^ array[j+1];
                  array[j] = array[j] ^ array[j+1];
              }
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章