剑指Offer前十题

来源:互联网 发布:全身美白 知乎 编辑:程序博客网 时间:2024/05/22 15:11

怒刷剑指offer

5/9/2017 2:27:17 PM

第二题 单例模式

1. 饿汉单例模式

public class Singleton {    private static final Singleton instance = new Singleton();    private Singleton() {};    public static Singleton getInstance() {        return instance;    }}

注意:(1)将实例用private static final修饰并在声明时初始化.(2)构造函数用private修饰。(3)获取实例的方法用static修饰

2.懒汉单例模式

public class Singleton [    private static Singleton instance = null;    private Singleton() {};    public synchronized static Singleton getInstance() {        if (instance == null) {            return new Singleton();        }        return instance;}

注意:(1)将实例用private static修饰并在声明时初始化为null.(2)构造函数用private修饰。(3)获取实例的方法用synchronized static修饰,若实例存在则返回实例,不存在则先创建再返回

第三题 二维数组的查找

题目描述:一个二维数组,每一行从左到右递增,每一列从上到下递增.输入一个二维数组和一个整数,判断数组中是否含有整数。

package t1_10;/*** * 问题描述:一个二维数组,从左到右递增,从上到下递增。查一个数target是否在这个二维数组中 * 解决思路:一个一个的遍历是可以解决问题,但是提升了时间复杂度。 * 因为该数组的数组元素是有规律的,所以可以先比较第一行的最后一列数,target大则再比较下一行,target小则列数向前推 *  * @author Administrator * */public class T3_Search {    public static void main(String[] args) {        int[][] testarray = new int[4][4];        testarray[0][0] = 1;        testarray[0][1] = 2;        testarray[0][2] = 8;        testarray[0][3] = 9;        testarray[1][0] = 2;        testarray[1][1] = 4;        testarray[1][2] = 9;        testarray[1][3] = 12;        testarray[2][0] = 4;        testarray[2][1] = 7;        testarray[2][2] = 10;        testarray[2][3] = 13;        testarray[3][0] = 6;        testarray[3][1] = 8;        testarray[3][2] = 11;        testarray[3][3] = 15;        for (int i = 0; i < testarray.length; i++) {            for (int j = 0; j < testarray[0].length; j++) {                System.out.print(testarray[i][j]+" ");            }            System.out.println();        }        System.out.println(find(testarray, 1));    }    public static boolean find(int[][] arr, int number) {        if (arr == null) {            return false;        }        int column = arr[0].length - 1;        int row = 0;        while (row < arr[0].length && column >= 0) {            if (arr[row][column] == number) {                return true;            } else if (arr[row][column] > number) {                column--;            } else {                row++;            }        }        return false;    }}

第四题 替换空格

package t1_10;/*** * 问题描述:将字符串的空格替换成“2%0” * 解决思路:遍历字符串的每一个字符,如果是空格则替换成“2%0”, * 注意:这边使用的是StringBuffer,因为String是不可变的 * @author Administrator * */public class T4_ReplaceBlank {    public static void main(String[] args) {        String input = "a b c";        System.out.println(replace(input));    }    public static String replace(String input) {        if (input == null) {            return null;        }        StringBuffer buffer = new StringBuffer();        for (int i = 0; i < input.length(); i++) {            if (input.charAt(i) == ' ') {                /*buffer.append("2");                buffer.append("%");                buffer.append("0");*/                buffer.append("2%0");            } else {                //buffer.append(String.valueOf(input.charAt(i)));                buffer.append(input.charAt(i));            }        }        return new String(buffer);    }}

第五题 从尾到头打印链表

1、非递归方式

package t1_10;import java.util.Stack;/*** * 题目:逆序输出链表 * 思路:利用栈后进先出的特性来实现链表的逆序输出 * @author Administrator * */public class T5_PrintListReverse {    public static void main(String[] args) {        ListNode node1 = new ListNode();        ListNode node2 = new ListNode();        ListNode node3 = new ListNode();        node1.data = 1;        node2.data = 2;        node3.data = 3;        node1.next = node2;        node2.next = node3;        System.out.println("递归方式:");        printLinkListD(node1);        System.out.println("非递归方式:");        printLinkList(node1);    }    //非递归    public static void printLinkList(ListNode head) {        if (head == null) {            return;        }        Stack<ListNode> stack = new Stack<ListNode>();        while (head != null) {            stack.push(head);            head = head.next;        }        while (!stack.empty()) {            System.out.println(stack.pop().data);        }    }    //递归方式    public static void printLinkListD(ListNode head) {        if (head != null){            if (head.next != null) {                printLinkListD(head.next);            }            System.out.println(head.data);        }    }    static class ListNode {        int data;        ListNode next;    }}

第六题 重建二叉树

题目描述:输入二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设前序遍历和中序遍历结果中都不包含重复的数字。

package t1_10;import java.util.Arrays;/*** * 题目:根据二叉树的前序遍历和中序遍历,求出该二叉树 * 思路:前序遍历和中序遍历相互参照,前序遍历的第一个元素为根节点,中序遍历根节点的前面为根节点的左儿子,后面为根节点的右儿子。采用递归方式 * @author Administrator * */public class T6_RebuildBinaryTree {    public static void main(String[] args) {        int[] preorder = { 1, 2, 4, 7, 3, 5, 6, 8 };        int[] inorder = { 4, 7, 2, 1, 5, 3, 8, 6 };        try {            printTree(preorder, inorder);        } catch (Exception e) {            e.printStackTrace();        }    }    public static BinaryTreeNode printTree(int[] preorder, int[] inorder)            throws Exception {        if (preorder == null || inorder == null) {            return null;        }        if (preorder.length != inorder.length) {            throw new Exception("长度不一样,非法输入!");        }        BinaryTreeNode root = new BinaryTreeNode();        for (int i = 0; i < preorder.length; i++) {            if (inorder[i] == preorder[0]) {                root.value = inorder[i];                System.out.println(root.value);                root.leftNode = printTree(                        Arrays.copyOfRange(preorder, 1, i + 1),                        Arrays.copyOfRange(inorder, 0, i));                root.rightNode = printTree(                        Arrays.copyOfRange(preorder, i + 1, preorder.length),                        Arrays.copyOfRange(inorder, i + 1, inorder.length));            }        }        return root;    }    static class BinaryTreeNode {        public int value;        public BinaryTreeNode leftNode;        public BinaryTreeNode rightNode;    }}

第七题 用两个栈实现队列

题目:用两个栈实现一个队列,实现对了的两个函数appendTail和deleteHead,分别完成在队列尾插入结点和在队列头部删除结点的功能

package t1_10;import java.util.Stack;/*** * 题目:使用两个栈实现一个队列的功能 * 分析:栈的特点为先进后出,队列的特点为先进先出,所以他们两个的特点是相反的。当进入队列时,压入stack1,当出队列时将stack1压入stack2,然后弹出stack2的栈顶. * @author Administrator * */public class T7_StackToList<T> {    private Stack<T> stack1 = new Stack<T>();    private Stack<T> stack2 = new Stack<T>();    public void appendTail(T ele) {        stack1.push(ele);    }    public T deleteHead() throws Exception {        if (stack2.empty()) {            while (!stack1.empty()) {                stack2.push(stack1.pop());            }        }        if (stack2.empty()) {            throw new Exception("列表为空,不能删除!");        }        return stack2.pop();    }    public static void main(String[] args) {        T7_StackToList<Integer> list = new T7_StackToList<Integer>();        list.appendTail(1);        list.appendTail(2);        list.appendTail(3);        try {            System.out.println(list.deleteHead());        } catch (Exception e) {            e.printStackTrace();        }    }}

第八题 旋转数组的最小数字

package t1_10;/* * 一个逐渐递增的数组(数组元素可以重复),将其前端子数组放到原数组的后面,我们称之为旋转数组。现给出一个旋转数组,要求出其最小的元素。 * 分析:(1)如果使用两个下标,一个下标初始化为0,另一个下标初始化为length-1。用后一个下标与前一个下标的值作比较,如果小于则第二个下标向前推进,直到第二个下标的值>=第一个元素,则去此时第二个下标-1.--但是这个前提是arr[length-1]<arr[0],如果相等则不成立 * (2)使用三个下标,left,right,mid。left初始化为0,right初始化为length-1,mid初始化为(left+right)/2,mid记录最终的最小数的下标。通过不断的确认left和right的范围,最终确认mid的值。 * 1.if arr[left] != arr[right],则通过和arr[mid]比较缩小left或right的范围 * 2.if arr[left] == arr[right] != arr[mid],则也可将left或right的范围 * 3.if arr[left] == arr[right] == arr[mid],只能左右分别移一个进来比较 *      left++,right++; */public class T8_RotateMin {    public static void main(String[] args) {        T8_RotateMin p8 = new T8_RotateMin();        // int[] array={1,1,1,2,0};        // int[] array={3,4,5,1,2};        // int[] array = { 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 };        // int[] array = { 3, 4, 5, 0, 1, 2, 3 };        // int[] array = {1, 2, 0, 1, 1, 1, 1};        int[] array = { 1, 1, 1, 1 };        System.out.println(p8.findMinNum(array));    }    public Integer findMinNum(int[] array) {        if (array == null) {            return null;        }        int leftIndex = 0;        int rightIndex = array.length - 1;        int mid = 0;        while (array[leftIndex] >= array[rightIndex]) {            if (rightIndex - leftIndex <= 1) {                mid = rightIndex;                break;            }            mid = (leftIndex + rightIndex) / 2;            if (array[leftIndex] == array[rightIndex]                    && array[leftIndex] == array[mid]) {                leftIndex++;                rightIndex--;            } else {                if (array[mid] >= array[leftIndex])                    leftIndex = mid;                else {                    if (array[mid] <= array[rightIndex])                        rightIndex = mid;                }            }        }        return array[mid];    }}

第九题 斐波那契数列

package t1_10;public class T9_Fibonacci {    public static void main(String[] args) {        int result;        try {            result = Fibonacci(3);            System.out.println(result);        } catch (Exception e) {            e.printStackTrace();        }    }    public static int Fibonacci(int n) throws Exception {        int preOne = 1;        int preTwo = 1;        int result = 0;        if (n < 1) {            throw new Exception("请输大于0的数!");        }        if (n == 1) {            return preOne;        }        if (n == 2) {            return preTwo;        }        for (int i = 3; i <= n; i++) {            result = preOne + preTwo;            preOne = preTwo;            preTwo = result;        }        return result;    }}

第十题 二进制中1的个数

package t1_10;/*** * 求一个数对应二进制1的个数 * @author Administrator * */public class T10_BinaryOneNumber {    public static void main(String[] args) {        int n = 15;        int count = BinaryOneNumber(n);        System.out.println(count);    }    public static int BinaryOneNumber(int n) {        int count = 0;        while (n !=0 ) {            count++;            n = n & (n - 1);    //每一次n和n-1求与运算,1的个数就减一        }        return count;    }}

有什么错误的地方还请多多指教

0 0