劍指Offer

S1

package SwordToOffer;
/**
 * 題目描述
在一個(gè)二維數(shù)組中,每一行都按照從左到右遞增的順序排序交惯,每一列都按照從上到下遞增的順序排序。
請(qǐng)完成一個(gè)函數(shù)卸夕,輸入這樣的一個(gè)二維數(shù)組和一個(gè)整數(shù),判斷數(shù)組中是否含有該整數(shù)睦袖。

 * @author panfei
 *
 */
public class S1 {

    public static void main(String[] args) {
        int[][] arr = {{1,2,3},{4,5,6}};
        System.out.println(Find(3,arr));
    }
    
    public static boolean Find(int target, int [][] array) {
        if(array == null || array.length <= 0)
            return false;
        for(int i =0;i<array.length;i++){
            for(int j=0;j<array[i].length;j++){
                if(target == array[i][j])
                    return true;
            }
        }
        return false;
    }
}

S2

package SwordToOffer;
/**
 * 請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù)葵第,將一個(gè)字符串中的空格替換成“%20”。
 * 例如纪岁,當(dāng)字符串為We Are Happy.則經(jīng)過替換之后的字符串為We%20Are%20Happy。
 * @author panfei
 *
 */
public class S2 {

    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("We are happy");
        System.out.println(replaceSpace(str));
    }
    
    public static String replaceSpace(StringBuffer str) {
        String s = str.toString();
        s = s.replace(" ", "%20");
        return s;
    }

}

s3

package SwordToOffer;

import java.util.ArrayList;

/**
 * 輸入一個(gè)鏈表则果,從尾到頭打印鏈表每個(gè)節(jié)點(diǎn)的值
 * 
 * @author panfei
 * 
 */
public class S3 {
    ArrayList<Integer> list = new ArrayList<Integer>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {

        if (listNode != null) {
            printListFromTailToHead(listNode.next);
            list.add(listNode.val);
        }
        return list;
    }

}

s4

package SwordToOffer;

/**
 * 輸入某二叉樹的前序遍歷和中序遍歷的結(jié)果幔翰,請(qǐng)重建出該二叉樹。 假設(shè)輸入的前序遍歷和中序遍歷的結(jié)果中都不含重復(fù)的數(shù)字西壮。
 * 例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6}遗增,則重建二叉樹并返回。
 * 
 * @author panfei
 * 
 */
public class S4 {

    public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        TreeNode root = reConstructBinaryTree(pre, 0, pre.length - 1, in, 0,
                in.length - 1);
        return root;
    }

    private TreeNode reConstructBinaryTree(int[] pre, int startPre, int endPre,
            int[] in, int startIn, int endIn) {
        if (startPre > endPre || startIn > endIn) {
            return null;
        }
        TreeNode root = new TreeNode(pre[startPre]);
        for (int i = startIn; i <= endIn; i++) {
            if (in[i] == pre[startPre]) {
                root.left = reConstructBinaryTree(pre, startPre + 1, startPre
                        + i - startIn, in, startIn, i - 1);
                root.right = reConstructBinaryTree(pre, i - startIn + startPre
                        + 1, endPre, in, i + 1, endIn);
            }
        }
        return root;
    }
}

s5

package SwordToOffer;

import java.util.Stack;

/**
 * 用兩個(gè)棧來(lái)實(shí)現(xiàn)一個(gè)隊(duì)列款青,完成隊(duì)列的Push和Pop操作做修。 隊(duì)列中的元素為int類型。
 * 
 * @author panfei
 * 
 */
public class S5 {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();

    public void push(int node) {
        stack1.push(node);
    }

    public int pop() {
        if (stack1.isEmpty() && stack2.isEmpty()) {
            throw new RuntimeException("Queue is Empty");
        }
        if (stack2.isEmpty()) {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();

    }
}

s6

package SwordToOffer;

/**
 * 把一個(gè)數(shù)組最開始的若干個(gè)元素搬到數(shù)組的末尾抡草,我們稱之為數(shù)組的旋轉(zhuǎn)饰及。 輸入一個(gè)非遞減排序的數(shù)組的一個(gè)旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素渠牲。
 * 例如數(shù)組{3,4,5,1,2}為{1,2,3,4,5}的一個(gè)旋轉(zhuǎn)旋炒,該數(shù)組的最小值為1步悠。 NOTE:給出的所有元素都大于0签杈,若數(shù)組大小為0,請(qǐng)返回0鼎兽。
 * 
 * @author panfei
 * 
 */
public class S6 {
    public static void main(String[] args) {
        int[] arr = { 3, 4, 5, 1, 2 };
        System.out.println(minNumberInRotateArray(arr));
    }

    public static int minNumberInRotateArray(int[] array) {
        if (array == null || array.length <= 0)
            return 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] > array[i + 1]) {
                return array[i + 1];
            }
        }
        return 0;
    }
}

s7

package SwordToOffer;

import java.util.Scanner;

/**
 * 大家都知道斐波那契數(shù)列答姥,現(xiàn)在要求輸入一個(gè)整數(shù)n,請(qǐng)你輸出斐波那契數(shù)列的第n項(xiàng)谚咬。n<=39
 * 
 * @author panfei
 * 
 */
public class S7 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        // System.out.println(Fibonacci(n));
        System.out.println(F2(n));
        sc.close();
    }

    public static int Fibonacci(int n) {
        if (n == 1 || n == 2)
            return 1;
        if (n > 2) {
            return Fibonacci(n - 1) + Fibonacci(n - 2);
        }
        return 0;
    }

    public static int F2(int n) {
        int res = 0;
        int a = 1;
        int b = 1;
        while (n - 2 > 0) {

            a = a + b;
            b = a - b;
            res = a;
            n--;
        }
        return res;
    }

}

s8

package SwordToOffer;

/**
 * 一只青蛙一次可以跳上1級(jí)臺(tái)階鹦付,也可以跳上2級(jí)。求該青蛙跳上一個(gè)n級(jí)的臺(tái)階總共有多少種跳法择卦。
 * 
 * @author panfei
 * 
 */
public class S8 {
    public int JumpFloor(int target) {
        if (target == 1 || target == 2) {
            return target;
        }

        return JumpFloor(target - 1) + JumpFloor(target - 2);
    }
}

s9

package SwordToOffer;

/**
 * 一只青蛙一次可以跳上1級(jí)臺(tái)階敲长,也可以跳上2級(jí)……它也可以跳上n級(jí)郎嫁。 求該青蛙跳上一個(gè)n級(jí)的臺(tái)階總共有多少種跳法。
 * 
 * @author panfei
 * 
 */
public class S9 {
    public int JumpFloorII(int target) {
        if (target == 1 || target == 2)
            return target;
        return 2 * JumpFloorII(target - 1);
    }
}

s10

package SwordToOffer;

/**
 * 我們可以用2*1的小矩形橫著或者豎著去覆蓋更大的矩形祈噪。 請(qǐng)問用n個(gè)2*1的小矩形無(wú)重疊地覆蓋一個(gè)2*n的大矩形泽铛,總共有多少種方法?
 * 
 * @author panfei
 * 
 */
public class S10 {

    public int RectCover(int target) {
        if (target <= 0)
            return 0;
        if (target == 1 || target == 2)
            return target;
        return RectCover(target - 1) + RectCover(target - 2);
    }
}

s11

package SwordToOffer;

import java.util.Scanner;

/**
 * 輸入一個(gè)整數(shù)辑鲤,輸出該數(shù)二進(jìn)制表示中1的個(gè)數(shù)盔腔。其中負(fù)數(shù)用補(bǔ)碼表示。
 * 
 * @author panfei
 * 
 */
public class S11 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        System.out.println(NumberOf1(n));
    }

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

s12

package SwordToOffer;

/**
 * 給定一個(gè)double類型的浮點(diǎn)數(shù)base和int類型的整數(shù)exponent月褥。求base的exponent次方弛随。
 * 
 * @author panfei
 * 
 */
public class S12 {
    public static void main(String[] args) {
        double base = 2.0d;
        int e = -4;
        System.out.println(Power(base,e));
    }

    public static double Power(double base, int exponent) {
        double res = 1.0d;
        for(int i=0;i<Math.abs(exponent);i++){
            res *= base;
        }
        if(exponent>=0){
            return res;
        }else{
            return 1/res;
        }
        //更簡(jiǎn)單的
//      return Math.pow(base, exponent);
        
    }
}

s13

package SwordToOffer;

/**
 * 輸入一個(gè)整數(shù)數(shù)組,實(shí)現(xiàn)一個(gè)函數(shù)來(lái)調(diào)整該數(shù)組中數(shù)字的順序宁赤, 使得所有的奇數(shù)位于數(shù)組的前半部分舀透,所有的偶數(shù)位于位于數(shù)組的后半部分,
 * 并保證奇數(shù)和奇數(shù)礁击,偶數(shù)和偶數(shù)之間的相對(duì)位置不變盐杂。
 * 
 * @author panfei
 * 
 */
public class S13 {
    public static void main(String[] args) {
        int[] arr = { 7, 2, 3, 1, 4 };
        // 7,2||3,1,4
        reOrderArray(arr);
    }

    public static void reOrderArray(int[] array) {
        int mid = array.length / 2;
        for (int i = 0; i < mid; i++) {
            for (int j = mid; j < array.length; j++) {
                if (array[i] % 2 == 0 && array[j] % 2 == 1) {
                    int temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
        }

        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }

    }
}

s14

package SwordToOffer;

/**
 * 輸入一個(gè)鏈表,輸出該鏈表中倒數(shù)第k個(gè)結(jié)點(diǎn)哆窿。
 * 
 * @author panfei
 * 
 */
public class S14 {
    public ListNode FindKthToTail(ListNode head, int k) {
        ListNode p, q;
        p = q = head;
        int i = 0;
        for (; p != null; i++) {
            if (i >= k)
                q = q.next;
            p = p.next;

        }
        return i < k ? null : q;

    }
}

s15

package SwordToOffer;

/**
 * 輸入一個(gè)鏈表链烈,反轉(zhuǎn)鏈表后,輸出鏈表的所有元素挚躯。
 * 
 * @author panfei
 * 
 */
public class S15 {
    public ListNode ReverseList(ListNode head) {
        if(head == null)
            return null;
        ListNode pre = null;
        ListNode next = null;
        while(head!=null){
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }
}

s16

package SwordToOffer;

/**
 * 輸入兩個(gè)單調(diào)遞增的鏈表强衡,輸出兩個(gè)鏈表合成后的鏈表, 當(dāng)然我們需要合成后的鏈表滿足單調(diào)不減規(guī)則码荔。
 * 
 * @author panfei
 * 
 */
public class S16 {
    public ListNode Merge(ListNode list1, ListNode list2) {
        if (list1 == null)
            return list2;
        if (list2 == null)
            return list1;
        if (list1.val < list2.val) {
            list1.next = Merge(list1.next, list2);
            return list1;
        } else {
            list2.next = Merge(list1, list2.next);
            return list2;
        }
    }
}

s17

package SwordToOffer;

/**
 * 輸入兩棵二叉樹A漩勤,B,判斷B是不是A的子結(jié)構(gòu)缩搅。(ps:我們約定空樹不是任意一個(gè)樹的子結(jié)構(gòu))
 * 
 * @author panfei
 * 
 */
public class S17 {
    public boolean HasSubtree(TreeNode root1, TreeNode root2) {
        if (root1 == null || root2 == null) {
            return false;
        }

        return isSubTree(root1, root2) || isSubTree(root1.left, root2)
                || isSubTree(root1.right, root2);
    }

    public boolean isSubTree(TreeNode root1, TreeNode root2) {
        if (root2 == null)
            return true;
        if (root1 == null)
            return false;
        if (root1.val == root2.val) {
            return isSubTree(root1.left, root2.left)
                    && isSubTree(root1.right, root2.right);
        } else {
            return false;
        }
    }
}

s18

package SwordToOffer;

import java.util.Stack;

/**
 * 操作給定的二叉樹越败,將其變換為源二叉樹的鏡像。
 * 
 * @author panfei
 * 
 */
public class S18 {

    public void Mirror(TreeNode root) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        if (root == null)
            return;
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if (node.left != null || node.right != null) {
                TreeNode temp = node.left;
                node.left = node.right;
                node.right = temp;
            }
            if (node.left != null)
                stack.push(node.left);
            if (node.right != null)
                stack.push(node.right);
        }

    }
}

s19

package SwordToOffer;

import java.util.ArrayList;

/**
 * 輸入一個(gè)矩陣硼瓣,按照從外向里以順時(shí)針的順序依次打印出每一個(gè)數(shù)字究飞, 例如,如果輸入如下矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
 * 15 16 則依次打印出數(shù)字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
 * 
 * @author panfei
 * 
 */
public class S19 {

    public static void main(String[] args) {
        int[][] arr = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 },
                { 13, 14, 15, 16 } };
        ArrayList list = printMatrix(arr);
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
    }

    public static ArrayList<Integer> printMatrix(int[][] matrix) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        int row = matrix.length;
        int col = matrix[0].length;
        if (row == 0 || col == 0)
            return null;
        int top = 0, left = 0, bottom = row - 1, right = col - 1;
        while (top <= bottom && left <= right) {
            // left-->right
            for (int i = left; i <= right; i++) {
                list.add(matrix[top][i]);
            }
            // top-->bottom
            for (int i = top + 1; i <= bottom; i++) {
                list.add(matrix[i][right]);
            }
            // right-->left
            if (top != bottom) {
                for (int i = right - 1; i >= left; i--) {
                    list.add(matrix[bottom][i]);
                }
            }
            // bottom-->top
            if (left != right) {
                for (int i = bottom - 1; i > top; i--) {
                    list.add(matrix[i][left]);
                }
            }
            left++;
            top++;
            right--;
            bottom--;
        }

        return list;

    }
}

s20

package SwordToOffer;

/**
 * 定義棧的數(shù)據(jù)結(jié)構(gòu)堂鲤,請(qǐng)?jiān)谠擃愋椭袑?shí)現(xiàn)一個(gè)能夠得到棧最小元素的min函數(shù)亿傅。
 * 
 * @author panfei
 * 
 */
import java.util.Stack;
public class S20 {
    
    public void push(int node) {
        
    }

    public void pop() {

    }

    public int top() {
        return 0;

    }

    public int min() {
        return 0;

    }
}

s21

package SwordToOffer;

import java.util.Stack;

/**
 * 輸入兩個(gè)整數(shù)序列,第一個(gè)序列表示棧的壓入順序瘟栖,請(qǐng)判斷第二個(gè)序列是否為該棧的彈出順序葵擎。
 * 假設(shè)壓入棧的所有數(shù)字均不相等。例如序列1,2,3,4,5是某棧的壓入順序半哟, 序列4酬滤,5,3,2,1是該壓棧序列對(duì)應(yīng)的一個(gè)彈出序列签餐,
 * 但4,3,5,1,2就不可能是該壓棧序列的彈出序列。 (注意:這兩個(gè)序列的長(zhǎng)度是相等的)
 * 
 * @author panfei
 * 
 */
public class S21 {
    public boolean IsPopOrder(int[] pushA, int[] popA) {
        if (pushA == null || popA == null)
            return false;
        Stack<Integer> stack = new Stack<Integer>();
        int popIndex = 0;
        for (int i = 0; i < pushA.length; i++) {
            stack.push(pushA[i]);
            // 若棧不為空,且棧頂元素等于彈出序列
            while (!stack.isEmpty() && stack.peek() == popA[popIndex]) {
                stack.pop();
                popIndex++;
            }
        }
        return stack.isEmpty();
    }
}

s22

package SwordToOffer;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 從上往下打印出二叉樹的每個(gè)節(jié)點(diǎn)盯串,同層節(jié)點(diǎn)從左至右打印贱田。(二叉樹的層次遍歷)
 * 
 * @author panfei
 * 
 */
public class S22 {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if (root == null)
            return list;

        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode treeNode = queue.poll();
            if (treeNode.left != null) {
                queue.offer(treeNode.left);
            }
            if (treeNode.right != null) {
                queue.offer(treeNode.right);
            }
            list.add(treeNode.val);
        }

        return list;
    }
}

s23

package SwordToOffer;

/**
 * 輸入一個(gè)整數(shù)數(shù)組,判斷該數(shù)組是不是某二叉搜索樹的后序遍歷的結(jié)果嘴脾。如果是則輸出Yes,否則輸出No男摧。 假設(shè)輸入的數(shù)組的任意兩個(gè)數(shù)字都互不相同。
 * 
 * @author panfei
 * 
 */
public class S23 {

    public boolean VerifySquenceOfBST(int[] sequence) {
        if (sequence.length == 0)
            return false;
        if (sequence.length == 1)
            return true;

        return judge(sequence, 0, sequence.length - 1);
    }

    public boolean judge(int[] arr, int start, int end) {
        if (start >= end)
            return true;
        int i = end;
        // 從后向前找
        while (i > start && arr[i - 1] > arr[end])
            i--;// 找到比根節(jié)點(diǎn)小的點(diǎn)
        for (int j = start; j < i - 1; j++) {
            if (arr[j] > arr[end]) {
                return false;
            }
        }

        return judge(arr, start, i - 1) && judge(arr, i, end - 1);
    }
}

s24

package SwordToOffer;

import java.util.ArrayList;

/**
 * 輸入一顆二叉樹和一個(gè)整數(shù)译打,打印出二叉樹中結(jié)點(diǎn)值的和為輸入整數(shù)的所有路徑. 路徑定義為從樹的根結(jié)點(diǎn)開始往下一直到葉結(jié)點(diǎn)所經(jīng)過的結(jié)點(diǎn)形成一條路徑耗拓。
 * 
 * @author panfei
 * 
 */
public class S24 {

    public ArrayList<Integer> list = new ArrayList<Integer>();
    public ArrayList<ArrayList<Integer>> allList = new ArrayList<ArrayList<Integer>>();

    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
        if (root == null)
            return allList;
        list.add(root.val);
        target -= root.val;
        if (target == 0 && root.left == null && root.right == null) {
            allList.add(new ArrayList<Integer>(list));
        }
        FindPath(root.left, target);
        FindPath(root.right, target);
        list.remove(list.size() - 1);
        return allList;
    }
}

s25

package SwordToOffer;

/**
 * 輸入一個(gè)復(fù)雜鏈表(每個(gè)節(jié)點(diǎn)中有節(jié)點(diǎn)值,以及兩個(gè)指針奏司, 一個(gè)指向下一個(gè)節(jié)點(diǎn)乔询,另一個(gè)特殊指針指向任意一個(gè)節(jié)點(diǎn)), 返回結(jié)果為復(fù)制后復(fù)雜鏈表的head韵洋。
 * (注意竿刁,輸出結(jié)果中請(qǐng)不要返回參數(shù)中的節(jié)點(diǎn)引用,否則判題程序會(huì)直接返回空)
 * 
 * @author panfei
 * 
 */
public class S25 {
    public RandomListNode Clone(RandomListNode pHead) {
        if (pHead == null)
            return null;
        // 開辟一個(gè)新節(jié)點(diǎn)
        RandomListNode pCloneHead = new RandomListNode(pHead.label);
        pCloneHead.next = pHead.next;
        pCloneHead.random = pHead.random;
        // 遞歸其他節(jié)點(diǎn)
        pCloneHead.next = Clone(pHead.next);
        return pCloneHead;
    }

    class RandomListNode {
        int label;
        RandomListNode next = null;
        RandomListNode random = null;

        public RandomListNode(int label) {
            this.label = label;
        }
    }
}

s26

package SwordToOffer;

/**
 * 輸入一棵二叉搜索樹搪缨,將該二叉搜索樹轉(zhuǎn)換成一個(gè)排序的雙向鏈表食拜。 要求不能創(chuàng)建任何新的結(jié)點(diǎn),只能調(diào)整樹中結(jié)點(diǎn)指針的指向副编。
 * 
 * @author panfei
 * 
 */
public class S26 {
    public TreeNode Convert(TreeNode pRootOfTree) {
        if (pRootOfTree == null)
            return null;
        if (pRootOfTree.left == null && pRootOfTree.right == null) {
            return pRootOfTree;
        }
        // 將左子樹構(gòu)造成雙鏈表,并返回鏈表頭節(jié)點(diǎn)
        TreeNode left = Convert(pRootOfTree.left);
        TreeNode p = left;
        // 定位至左子樹雙聯(lián)表最后一個(gè)節(jié)點(diǎn)
        while (p != null && p.right != null) {
            p = p.right;
        }
        // 如果左子樹鏈表不為空的話,將當(dāng)前root追加到左子樹鏈表
        if (left != null) {
            p.right = pRootOfTree;
            pRootOfTree.left = p;
        }
        // 將右子樹構(gòu)造成雙聯(lián)表,并返回鏈表頭節(jié)點(diǎn)
        TreeNode right = Convert(pRootOfTree.right);
        // 如果右子樹鏈表不為空的話负甸,將該鏈表追加到root節(jié)點(diǎn)之后
        if (right != null) {
            right.left = pRootOfTree;
            pRootOfTree.right = right;
        }
        return left != null ? left : pRootOfTree;
    }
}

s27

package SwordToOffer;

import java.util.ArrayList;
import java.util.Collections;

/**
 * 輸入一個(gè)字符串(長(zhǎng)度不超過9(可能有字符重復(fù)),字符只包括大小寫字母),按字典序打印出該字符串中字符的所有排列。
 * 例如輸入字符串a(chǎn)bc,則打印出由字符a,b,c所能排列出來(lái)的所有字符串a(chǎn)bc,acb,bac,bca,cab和cba痹届。
 * 
 * @author panfei
 * 
 */
public class S27 {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> res = new ArrayList<String>();
        if (str != null && str.length() > 0) {
            PermutationHelper(str.toCharArray(), 0, res);
            Collections.sort(res);
        }
        return res;
    }

    public static void PermutationHelper(char[] c, int i, ArrayList<String> list) {
        if (i == c.length - 1) {// 解空間的一個(gè)葉節(jié)點(diǎn)
            list.add(String.valueOf(c));// 找到一個(gè)解

        } else {
            for (int j = i; j < c.length; j++) {
                if (j == i || c[j] != c[i]) {
                    swap(c, i, j);
                    PermutationHelper(c, i + 1, list);
                    swap(c, i, j);// 復(fù)位
                }
            }
        }
    }

    public static void swap(char[] c, int i, int j) {
        char temp = c[i];
        c[i] = c[j];
        c[j] = temp;
    }

}

s28

package SwordToOffer;

/*
 * 數(shù)組中有一個(gè)數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長(zhǎng)度的一半呻待,請(qǐng)找出這個(gè)數(shù)字。
 * 例如輸入一個(gè)長(zhǎng)度為9的數(shù)組{1,2,3,2,2,2,5,4,2}队腐。
 * 由于數(shù)字2在數(shù)組中出現(xiàn)了5次蚕捉,超過數(shù)組長(zhǎng)度的一半,因此輸出2柴淘。如果不存在則輸出0迫淹。
 * 
 * --------其他思路:先排序,若存在符合條件的數(shù),則一定是數(shù)組中間的那個(gè)數(shù)
 */
public class S28 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 2, 2, 2, 2, 5, 4, 2 };
        System.out.println(MoreThanHalfNum_Solution(arr));
    }

    // O(n)解法
    public static int MoreThanHalfNum_Solution(int[] array) {
        if (array.length == 0)
            return 0;
        int len = array.length;
        int num = array[0];
        int count = 1;
        for (int i = 1; i < len; i++) {
            if (num == array[i]) {
                count++;
            } else {
                count--;
            }
            if (count == 0) {
                num = array[i];
                count = 1;
            }
        }
        count = 0;
        for (int i = 0; i < len; i++) {
            if (num == array[i])
                count++;
        }
        if (2 * count > len)
            return num;

        return 0;
    }
}

s29

package SwordToOffer;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * 輸入n個(gè)整數(shù),找出其中最小的K個(gè)數(shù)悠就。例如輸入4,5,1,6,2,7,3,8這8個(gè)數(shù)字千绪,則最小的4個(gè)數(shù)字是1,2,3,4,充易。
 * 
 * @author panfei
 * 
 */
public class S29 {
    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if (input.length < k)
            return list;
        Arrays.sort(input);
        for (int i = 0; i < k; i++) {
            list.add(input[i]);
        }
        return list;
    }
}

s30

package SwordToOffer;

/**
 * HZ偶爾會(huì)拿些專業(yè)問題來(lái)忽悠那些非計(jì)算機(jī)專業(yè)的同學(xué)梗脾。 今天測(cè)試組開完會(huì)后,他又發(fā)話了:在古老的一維模式識(shí)別中,常常需要計(jì)算連續(xù)子向量的最大和,
 * 當(dāng)向量全為正數(shù)的時(shí)候 ,問題很好解決。但是, 如果向量中包含負(fù)數(shù),是否應(yīng)該包含某個(gè)負(fù)數(shù),并期望旁邊的正數(shù)會(huì)彌補(bǔ)它呢盹靴?
 * 例如:{6,-3,-2,7,-15,1,2,2},連續(xù)子向量的最大和為8(從第0個(gè)開始,到第3個(gè)為止)炸茧。 你會(huì)不會(huì)被他忽悠兹鸶尽?(子向量的長(zhǎng)度至少是1)
 * 
 * @author panfei
 * 
 */
public class S30 {

    public static void main(String[] args) {
        int[] arr = { 6, -3, -2, 7, -15, 1, 2, 2 };
        System.out.println(FindGreatestSumOfSubArray(arr));
    }

    //一維dp
    public static int FindGreatestSumOfSubArray(int[] array) {
        if (array == null || array.length <= 0) {
            return 0;
        }
        int sum = array[0];
        int temp = array[0];
        for (int i = 1; i < array.length; i++) {
            temp = temp < 0 ? array[i] : temp + array[i];
            sum = temp > sum ? temp : sum;
        }
        return sum;
    }
}

s31

package SwordToOffer;

/**
 * 求出1~13的整數(shù)中1出現(xiàn)的次數(shù),并算出100~1300的整數(shù)中1出現(xiàn)的次數(shù)梭冠?
 * 為此他特別數(shù)了一下1~13中包含1的數(shù)字有1辕狰、10、11控漠、12蔓倍、13因此共出現(xiàn)6次, 但是對(duì)于后面問題他就沒轍了。
 * ACMer希望你們幫幫他,并把問題更加普遍化,可以很快的求出任意非負(fù)整數(shù)區(qū)間中1出現(xiàn)的次數(shù)盐捷。
 * 
 * @author panfei
 * 
 *備注:給一個(gè)最簡(jiǎn)單的代碼偶翅,具體解釋可以去leetcode上面去看。
 *https://leetcode.com/discuss/44281/4-lines-o-log-n-c-java-python
 */
public class S31 {
    public int NumberOf1Between1AndN_Solution(int n) {
        int ones = 0;
        for (long m = 1; m <= n; m *= 10) {
            ones += (n / m + 8) / 10 * m + (n / m % 10 == 1 ? n % m + 1 : 0);
        }
        return ones;
    }
}

s32

package SwordToOffer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * 輸入一個(gè)正整數(shù)數(shù)組碉渡,把數(shù)組里所有數(shù)字拼接起來(lái)排成一個(gè)數(shù)聚谁,打印能拼接出的所有數(shù)字中最小的一個(gè)。
 * 例如輸入數(shù)組{3滞诺,32形导,321},則打印出這三個(gè)數(shù)字能排成的最小數(shù)字為321323习霹。
 * 
 * @author panfei
 * 
 */
public class S32 {

    public static void main(String[] args) {
        int[] arr = { 3, 32, 321 };
        System.err.println(PrintMinNumber(arr));
    }

    public static String PrintMinNumber(int[] numbers) {
        String res = "";
        ArrayList<Integer> list = new ArrayList<Integer>();
        int len = numbers.length;
        for (int i = 0; i < len; i++) {
            list.add(numbers[i]);
        }
        Collections.sort(list, new Comparator<Integer>() {
            public int compare(Integer str1, Integer str2) {
                String s1 = str1 + "" + str2;
                String s2 = str2 + "" + str1;
                return s1.compareTo(s2);
            }
        });
        for (int i : list) {
            res += i;
        }
        return res;
    }
}

s33

package SwordToOffer;

import java.util.ArrayList;

/**
 * 把只包含因子2朵耕、3和5的數(shù)稱作丑數(shù)(Ugly Number)。例如6淋叶、8都是丑數(shù)憔披, 但14不是,因?yàn)樗蜃?爸吮。 習(xí)慣上我們把1當(dāng)做是第一個(gè)丑數(shù)芬膝。
 * 求按從小到大的順序的第N個(gè)丑數(shù)
 * 
 * @author panfei
 * 
 */
public class S33 {
    public int GetUglyNumber_Solution(int index) {
        if (index <= 0)
            return 0;
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        int q2 = 0, q3 = 0, q5 = 0;
        while (list.size() < index) {
            int m2 = list.get(q2) * 2;
            int m3 = list.get(q3) * 3;
            int m5 = list.get(q5) * 5;
            int min = Math.min(m2, Math.min(m3, m5));
            list.add(min);
            if (min == m2)
                q2++;
            if (min == m3)
                q3++;
            if (min == m5)
                q5++;

        }
        return list.get(list.size() - 1);
    }
}

s34

package SwordToOffer;

/**
 * 在一個(gè)字符串(1<=字符串長(zhǎng)度<=10000,全部由字母組成)中 找到第一個(gè)只出現(xiàn)一次的字符,并返回它的位置
 * 
 * @author panfei
 * 
 */
public class S34 {
    public int FirstNotRepeatingChar(String str) {
        char[] c = str.toCharArray();
        int[] a = new int['z' + 1];
        for (char ch : c) {
            a[(int) ch]++;
        }
        for (int i = 0; i < c.length; i++) {
            if (a[(int) c[i]] == 1) {
                return i;
            }
        }
        return -1;
    }
}

s35

package SwordToOffer;
/**
 * 在數(shù)組中的兩個(gè)數(shù)字形娇,如果前面一個(gè)數(shù)字大于后面的數(shù)字锰霜,則這兩個(gè)數(shù)字組成一個(gè)逆序?qū)Α? * 輸入一個(gè)數(shù)組,求出這個(gè)數(shù)組中的逆序?qū)Φ目倲?shù)P。
 * 并將P對(duì)1000000007取模的結(jié)果輸出桐早。 即輸出P%1000000007
 * @author panfei
 *
 */
public class S35 {
    
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,0};
        System.out.println(InversePairs(arr));
    }
    
public static int InversePairs(int [] array) {
    
    return 0;
    }
}

s36

package SwordToOffer;

/**
 * 輸入兩個(gè)鏈表癣缅,找出它們的第一個(gè)公共結(jié)點(diǎn)。
 * 
 * @author panfei
 * 
 */
public class S36 {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        int len1 = getLength(pHead1);
        int len2 = getLength(pHead2);

        if (len1 > len2) {
            pHead1 = clearGap(pHead1, len1 - len2);
        } else {
            pHead2 = clearGap(pHead2, len2 - len1);
        }
        while (pHead1 != null) {
            if (pHead1 == pHead2)
                return pHead1;
            pHead1 = pHead1.next;
            pHead2 = pHead2.next;
        }

        return null;
    }

    public ListNode clearGap(ListNode node, int gap) {
        while (gap-- != 0) {
            node = node.next;
        }
        return node;
    }

    public int getLength(ListNode pHead) {
        if (pHead == null)
            return 0;
        int sum = 1;
        while (pHead.next != null)
            sum++;
        return sum;

    }
}

s37

package SwordToOffer;

/**
 * 統(tǒng)計(jì)一個(gè)數(shù)字在排序數(shù)組中出現(xiàn)的次數(shù)哄酝。
 * 
 * @author panfei
 * 
 */
public class S37 {
    public int GetNumberOfK(int[] array, int k) {
        int count = 0;
        if (array == null || array.length <= 0)
            return 0;
        for (int i = 0; i < array.length; i++) {
            if (k == array[i])
                count++;
        }
        return count;
    }
}

s38

package SwordToOffer;

/**
 * 輸入一棵二叉樹友存,求該樹的深度。 從根結(jié)點(diǎn)到葉結(jié)點(diǎn)依次經(jīng)過的結(jié)點(diǎn)(含根陶衅、葉結(jié)點(diǎn))形成樹的一條路徑屡立, 最長(zhǎng)路徑的長(zhǎng)度為樹的深度。
 * 
 * @author panfei
 * 
 */
public class S38 {
    public int TreeDepth(TreeNode root) {
        if (root == null)
            return 0;

        return Math.max(TreeDepth(root.left), TreeDepth(root.right)) + 1;
    }
}

s39

package SwordToOffer;

/**
 * 輸入一棵二叉樹搀军,判斷該二叉樹是否是平衡二叉樹膨俐。
 * 
 * @author panfei
 * 
 */
public class S39 {
    public boolean isBalanced = true;

    public boolean IsBalanced_Solution(TreeNode root) {
        getDepth(root);
        return isBalanced;
    }

    public int getDepth(TreeNode root) {
        if (root == null)
            return 0;
        int left = getDepth(root.left);
        int right = getDepth(root.right);
        if (Math.abs(left - right) > 1) {
            isBalanced = false;
        }
        return right > left ? right + 1 : left + 1;
    }

}

s40

package SwordToOffer;

/**
 * 一個(gè)整型數(shù)組里除了兩個(gè)數(shù)字之外勇皇,其他的數(shù)字都出現(xiàn)了兩次。請(qǐng)寫程序找出這兩個(gè)只出現(xiàn)一次的數(shù)字焚刺。
 * 
 * @author panfei
 * 
 */
public class S40 {
    // num1,num2分別為長(zhǎng)度為1的數(shù)組敛摘。傳出參數(shù)
    // 將num1[0],num2[0]設(shè)置為返回結(jié)果
    public void FindNumsAppearOnce(int[] array, int num1[], int num2[]) {
        if (array == null || array.length <= 1) {
            num1[0] = num1[0] = 0;
            return;
        }
        int len = array.length, index = 0, sum = 0;
        for (int i = 0; i < len; i++) {
            sum ^= array[i];
        }
        for (index = 0; index < 32; index++) {
            if ((sum & (1 << index)) != 0)
                break;
        }
        for (int i = 0; i < len; i++) {
            if ((array[i] & (1 << index)) != 0) {
                num2[0] ^= array[i];
            } else {
                num1[0] ^= array[i];
            }
        }
    }

    /**
     * 數(shù)組a中只有一個(gè)數(shù)出現(xiàn)一次,其他數(shù)都出現(xiàn)了2次乳愉,找出這個(gè)數(shù)字
     */
    public static int findForm(int[] a) {
        int len = a.length, res = 0;
        for (int i = 0; i < a.length; i++) {
            res = res ^ a[i];
        }
        return res;
    }

    /**
     * 數(shù)組a中只有一個(gè)數(shù)出現(xiàn)一次兄淫,其他數(shù)字都出現(xiàn)了3次,找出這個(gè)數(shù)字
     */
    public static int getNum(int[] arr) {
        int[] bits = new int[32];
        int len = arr.length;
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < 32; j++) {
                bits[j] = bits[j] + ((arr[i] >>> j) & 1);
            }
        }
        int res = 0;
        for (int i = 0; i < 32; i++) {
            if (bits[i] % 3 != 0) {
                res = res | (1 << i);
            }
        }
        return res;
    }

}

s41

package SwordToOffer;

import java.util.ArrayList;

/**
 * 小明很喜歡數(shù)學(xué),有一天他在做數(shù)學(xué)作業(yè)時(shí),要求計(jì)算出9~16的和,他馬上就寫出了正確答案是100蔓姚。
 * 但是他并不滿足于此,他在想究竟有多少種連續(xù)的正數(shù)序列的和為100(至少包括兩個(gè)數(shù))拖叙。
 * 沒多久,他就得到另一組連續(xù)正數(shù)和為100的序列:18,19,20,21,22。現(xiàn)在把問題交給你,你能不能也很快的找出所有和為S的連續(xù)正數(shù)序列? Good
 * Luck!
 * 
 * @author panfei
 * 
 */
public class S41 {
    public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> allList = new ArrayList<ArrayList<Integer>>();
        if (sum <= 1)
            return allList;
        int start = 1, end = 2;
        while (start != (sum + 1) / 2) {
            int cur = getSum(start, end);
            if (cur == sum) {
                ArrayList<Integer> list = new ArrayList<Integer>();
                for (int i = start; i <= end; i++) {
                    list.add(i);
                }
                allList.add(list);
                start++;
                end++;
            } else if (cur < sum) {
                end++;
            } else {
                start++;
            }
        }
        return allList;
    }

    public int getSum(int start, int end) {
        int sum = 0;
        for (int i = start; i <= end; i++) {
            sum += i;
        }
        return sum;
    }
}

s42

package SwordToOffer;

import java.util.ArrayList;

/**
 * 輸入一個(gè)遞增排序的數(shù)組和一個(gè)數(shù)字S赂乐,在數(shù)組中查找兩個(gè)數(shù)薯鳍, 是的他們的和正好是S,如果有多對(duì)數(shù)字的和等于S挨措,輸出兩個(gè)數(shù)的乘積最小的挖滤。
 * 
 * @author panfei
 * 
 */
public class S42 {
    public ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if (array == null || array.length <= 0) {
            return list;
        }
        int start = 0, end = array.length - 1;
        while (start < end) {
            if (array[start] + array[end] == sum) {
                list.add(array[start]);
                list.add(array[end]);
                return list;
            } else if (array[start] + array[end] > sum) {
                end--;
            } else {
                start++;
            }
        }
        return list;
    }
}

s43

package SwordToOffer;

/**
 * 匯編語(yǔ)言中有一種移位指令叫做循環(huán)左移(ROL),現(xiàn)在有個(gè)簡(jiǎn)單的任務(wù)浅役,就是用字符串模擬這個(gè)指令的運(yùn)算結(jié)果斩松。
 * 對(duì)于一個(gè)給定的字符序列S,請(qǐng)你把其循環(huán)左移K位后的序列輸出觉既。
 * 例如惧盹,字符序列S=”abcXYZdef”,要求輸出循環(huán)左移3位后的結(jié)果,即“XYZdefabc”瞪讼。是不是很簡(jiǎn)單钧椰?OK,搞定它符欠!
 * 
 * @author panfei
 * 
 */
public class S43 {

    public static void main(String[] args) {
        String str = "abcXYZdef";
        System.out.println(LeftRotateString(str, 3));
    }

    public static String LeftRotateString(String str, int n) {
        String res = "";
        if (str == null || str.length() <= 0)
            return res;
        String s1 = str.substring(0, n);
        String s2 = str.substring(n, str.length());
        res = s2 + s1;
        return res;
    }
}

s44

package SwordToOffer;

/**
 * 诺障迹客最近來(lái)了一個(gè)新員工Fish,每天早晨總是會(huì)拿著一本英文雜志希柿,寫些句子在本子上诊沪。
 * 同事Cat對(duì)Fish寫的內(nèi)容頗感興趣,有一天他向Fish借來(lái)翻看曾撤,但卻讀不懂它的意思端姚。 例如,“student. a am
 * I”挤悉。后來(lái)才意識(shí)到渐裸,這家伙原來(lái)把句子單詞的順序翻轉(zhuǎn)了, 正確的句子應(yīng)該是“I am a student.”。
 * Cat對(duì)一一的翻轉(zhuǎn)這些單詞順序可不在行橄仆,你能幫助他么?
 * 
 * @author panfei
 * 
 */
public class S44 {

    public static void main(String[] args) {
        String str = "I am a student.";
        String s1 = "";
        System.out.println(ReverseSentence(s1));
    }

    public static String ReverseSentence(String str) {
        if (str == null || str.length() <= 0)
            return str;
        String[] s = str.split(" ");
        StringBuffer sb = new StringBuffer();
        for (int i = s.length - 1; i > 0; i--) {
            sb.append(s[i]).append(" ");
        }
        sb.append(s[0]);
        return sb.toString();
    }
}

s45

package SwordToOffer;

/**
 * LL今天心情特別好,因?yàn)樗ベI了一副撲克牌,發(fā)現(xiàn)里面居然有2個(gè)大王,2個(gè)小王(一副牌原本是54張^_^)...
 * 他隨機(jī)從中抽出了5張牌,想測(cè)測(cè)自己的手氣,看看能不能抽到順子,如果抽到的話,他決定去買體育彩票,嘿嘿P普丁盆顾!“紅心A,黑桃3,小王,大王,方片5”,“Oh
 * My God!”不是順子.....LL不高興了,他想了想,決定大\小
 * 王可以看成任何數(shù)字,并且A看作1,J為11,Q為12,K為13。上面的5張牌就可以變成“1,2,3,4,5”(大小王分別看作2和4),“So
 * Lucky!”畏梆。LL決定去買體育彩票啦您宪。 現(xiàn)在,要求你使用這幅牌模擬上面的過程,然后告訴我們LL的運(yùn)氣如何。為了方便起見,你可以認(rèn)為大小王是0奠涌。
 * 
 * @author panfei
 * 
 */
public class S45 {
    /**
     * 需要滿足:1.除0外沒有重復(fù)的數(shù)      2.max - min < 5
     * 
     * @param numbers
     * @return
     */
    public boolean isContinuous(int[] numbers) {
        if (numbers == null || numbers.length <= 0)
            return false;
        int min = 14;
        int max = -1;
        int[] d = new int[14];
        d[0] = -5;
        int len = numbers.length;
        for (int i = 0; i < len; i++) {
            d[numbers[i]]++;
            if (numbers[i] == 0) {
                continue;
            }
            if (d[numbers[i]] > 1) {
                return false;
            }
            if (numbers[i] > max) {
                max = numbers[i];
            }
            if (numbers[i] < min) {
                min = numbers[i];
            }
        }
        if (max - min < 5)
            return true;
        return false;
    }
}

s46

package SwordToOffer;

/**
 * 每年六一兒童節(jié),畔芫蓿客都會(huì)準(zhǔn)備一些小禮物去看望孤兒院的小朋友,今年亦是如此。 HF作為帕锍客的資深元老,自然也準(zhǔn)備了一些小游戲捏卓。
 * 其中,有個(gè)游戲是這樣的:首先,讓小朋友們圍成一個(gè)大圈。 然后,他隨機(jī)指定一個(gè)數(shù)m,讓編號(hào)為0的小朋友開始報(bào)數(shù)慈格。
 * 每次喊到m-1的那個(gè)小朋友要出列唱首歌,然后可以在禮品箱中任意的挑選禮物,并且不再回到圈中,
 * 從他的下一個(gè)小朋友開始,繼續(xù)0...m-1報(bào)數(shù)....這樣下去....
 * 直到剩下最后一個(gè)小朋友,可以不用表演,并且拿到诺∏纾客名貴的“名偵探柯南”典藏版(名額有限哦!!^_^)。
 * 請(qǐng)你試著想下,哪個(gè)小朋友會(huì)得到這份禮品呢浴捆?(注:小朋友的編號(hào)是從0到n-1)
 * 
 * @author panfei
 * 
 */
public class S46 {
    public int LastRemaining_Solution(int n, int m) {
        if (n == 0)
            return -1;
        if (n == 1)
            return 0;
        else {
            return (LastRemaining_Solution(n - 1, m) + m) % n;
        }
    }
}

s47

package SwordToOffer;

/**
 * 求1+2+3+...+n蒜田,要求不能使用乘除法、for选泻、while冲粤、if、else页眯、switch梯捕、case等關(guān)鍵字及條件判斷語(yǔ)句(A?B:C)。
 * 
 * @author panfei
 * 
 */
public class S47 {
    /**
     * 
     解題思路: 
     * 1.需利用邏輯與的短路特性實(shí)現(xiàn)遞歸終止窝撵。
     * 2.當(dāng)n==0時(shí)科阎,(n>0)&&((sum+=Sum_Solution(n-1))>0)只執(zhí)行前面的判斷,為false忿族,然后直接返回0锣笨;
     * 3.當(dāng)n>0時(shí),執(zhí)行sum+=Sum_Solution(n-1)道批,實(shí)現(xiàn)遞歸計(jì)算Sum_Solution(n)错英。
     * 
     * @param n
     * @return
     */
    public int Sum_Solution(int n) {
        int res = n;
        boolean ans = (n > 0) && ((res += Sum_Solution(n - 1)) > 0);
        return res;
    }
}

s48

package SwordToOffer;

/**
 * 寫一個(gè)函數(shù),求兩個(gè)整數(shù)之和隆豹,要求在函數(shù)體內(nèi)不得使用+椭岩、-、*、/四則運(yùn)算符號(hào)
 * 
 * @author panfei
 * 
 */
public class S48 {
    public int Add(int num1, int num2) {
        while (num2 != 0) {
            int temp = num1 ^ num2;
            num2 = (num1 & num2) << 1;
            num1 = temp;
        }
        return num1;
    }

    /**
     * 首先看十進(jìn)制是如何做的: 5+7=12判哥,三步走 第一步:相加各位的值献雅,不算進(jìn)位,得到2塌计。 第二步:計(jì)算進(jìn)位值挺身,得到10.
     * 如果這一步的進(jìn)位值為0,那么第一步得到的值就是最終結(jié)果锌仅。
     * 
     * 第三步:重復(fù)上述兩步章钾,只是相加的值變成上述兩步的得到的結(jié)果2和10,得到12热芹。
     * 
     * 同樣我們可以用三步走的方式計(jì)算二進(jìn)制值相加: 5-101贱傀,7-111
     * 第一步:相加各位的值,不算進(jìn)位伊脓,得到010府寒,二進(jìn)制每位相加就相當(dāng)于各位做異或操作,101^111报腔。
     * 
     * 第二步:計(jì)算進(jìn)位值椰棘,得到1010,相當(dāng)于各位做與操作得到101榄笙,再向左移一位得到1010邪狞,(101&111)<<1。
     * 
     * 第三步重復(fù)上述兩步茅撞, 各位相加 010^1010=1000帆卓,進(jìn)位值為100=(010&1010)<<1。 繼續(xù)重復(fù)上述兩步:1000^100 =
     * 1100米丘,進(jìn)位值為0剑令,跳出循環(huán),1100為最終結(jié)果拄查。
     */
}

s49

/**
 * 將一個(gè)字符串轉(zhuǎn)換成一個(gè)整數(shù)吁津,要求不能使用字符串轉(zhuǎn)換整數(shù)的庫(kù)函數(shù)。 數(shù)值為0或者字符串不是一個(gè)合法的數(shù)值則返回0
 * 
 * @author panfei
 * 
 */
public class S49 {
    public int StrToInt(String str) {
        char[] c = str.toCharArray();
        return 0;
    }
}

s50

package SwordToOffer;

/**
 * 在一個(gè)長(zhǎng)度為n的數(shù)組里的所有數(shù)字都在0到n-1的范圍內(nèi)堕扶。 數(shù)組中某些數(shù)字是重復(fù)的碍脏,但不知道有幾個(gè)數(shù)字是重復(fù)的。
 * 也不知道每個(gè)數(shù)字重復(fù)幾次稍算。請(qǐng)找出數(shù)組中任意一個(gè)重復(fù)的數(shù)字典尾。
 * 例如,如果輸入長(zhǎng)度為7的數(shù)組{2,3,1,0,2,5,3}糊探,那么對(duì)應(yīng)的輸出是第一個(gè)重復(fù)的數(shù)字2钾埂。
 */
public class S50 {

    // Parameters:
    //    numbers:     an array of integers
    //    length:      the length of array numbers
    //    duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
    //                  Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
    //    這里要特別注意~返回任意重復(fù)的一個(gè)河闰,賦值duplication[0]
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    public boolean duplicate(int numbers[], int length, int[] duplication) {
        boolean[] k = new boolean[length];
        for (int i = 0; i < k.length; i++) {
            if (k[numbers[i]] == true) {
                duplication[0] = numbers[i];
                return true;
            }
            k[numbers[i]] = true;
        }
        return false;
    }

}

s51

package SwordToOffer;

/**
 * 給定一個(gè)數(shù)組A[0,1,...,n-1],請(qǐng)構(gòu)建一個(gè)數(shù)組B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法褥紫。
 * <p>
 * 思路
 * B[i]的值可以看作下圖的矩陣中每行的乘積姜性。
 * 下三角用連乘可以很容求得,上三角髓考,從下向上也是連乘部念。
 * 因此我們的思路就很清晰了,先算下三角中的連乘绳军,即我們先算出B[i]中的一部分印机,然后倒過來(lái)按上三角中的分布規(guī)律矢腻,把另一部分也乘進(jìn)去门驾。
 */
public class S51 {
    public int[] multiply(int[] A) {
        int[] B = new int[A.length];
        if (A.length != 0) {
            B[0] = 1;
            //計(jì)算下三角連乘
            for (int i = 1; i < A.length; i++) {
                B[i] = B[i - 1] * A[i - 1];
            }
            int temp = 1;
            //計(jì)算上三角
            for (int j = A.length - 2; j >= 0; j--) {
                temp *= A[j + 1];
                B[j] *= temp;
            }
        }
        return B;
    }

}

s52

package SwordToOffer;

/**
 * 請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù)用來(lái)匹配包括'.'和'*'的正則表達(dá)式。模式中的字符'.'表示任意一個(gè)字符多柑,而'*'表示它前面的字符可以出現(xiàn)任意次(包含0次)奶是。
 * 在本題中,匹配是指字符串的所有字符匹配整個(gè)模式竣灌。例如聂沙,字符串"aaa"與模式"a.a"和"ab*ac*a"匹配,但是與"aa.a"和"ab*a"均不匹配
 * <p>
 * 思路:
 * <p>
 * 當(dāng)模式中的第二個(gè)字符不是“*”時(shí):
 * 1初嘹、如果字符串第一個(gè)字符和模式中的第一個(gè)字符相匹配及汉,那么字符串和模式都后移一個(gè)字符,然后匹配剩余的屯烦。
 * 2坷随、如果字符串第一個(gè)字符和模式中的第一個(gè)字符相不匹配,直接返回false驻龟。
 * <p>
 * 而當(dāng)模式中的第二個(gè)字符是“*”時(shí):
 * 如果字符串第一個(gè)字符跟模式第一個(gè)字符不匹配温眉,則模式后移2個(gè)字符,繼續(xù)匹配翁狐。如果字符串第一個(gè)字符跟模式第一個(gè)字符匹配类溢,可以有3種匹配方式:
 * 1、模式后移2字符露懒,相當(dāng)于x*被忽略闯冷;
 * 2、字符串后移1字符懈词,模式后移2字符窃躲;
 * 3、字符串后移1字符钦睡,模式不變蒂窒,即繼續(xù)匹配字符下一位躁倒,因?yàn)?可以匹配多位;
 */
public class S52 {
    public boolean match(char[] str, char[] pattern) {
        if (str == null || pattern == null)
            return false;
        int strIndex = 0;
        int patternIndex = 0;
        return matchCore(str, strIndex, pattern, patternIndex);
    }

    private boolean matchCore(char[] str, int strIndex, char[] pattern, int patternIndex) {
        //有效性監(jiān)測(cè),str到尾,pattern到尾
        if (strIndex == str.length && patternIndex == pattern.length) {
            return true;
        }
        //pattern先到尾失敗
        if (strIndex != str.length && patternIndex == pattern.length) {
            return false;
        }
        //模式第二個(gè)是*,且字符串第一個(gè)和模式第一個(gè)匹配,分三種匹配模式,如不匹配,洒琢,模式后移
        if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {

            if ((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)) {
                return matchCore(str, strIndex, pattern, patternIndex + 2)//模式后移2秧秉,視為x*匹配0個(gè)字符
                        || matchCore(str, strIndex + 1, pattern, patternIndex + 2)//視為模式匹配1個(gè)字符
                        || matchCore(str, strIndex + 1, pattern, patternIndex);//*匹配1個(gè),再匹配str中的下一個(gè)
            } else {
                return matchCore(str, strIndex, pattern, patternIndex + 2);
            }
        }
        //模式第2個(gè)不是*衰抑,且字符串第1個(gè)跟模式第1個(gè)匹配象迎,則都后移1位,否則直接返回false
        if ((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)) {
            return matchCore(str, strIndex + 1, pattern, patternIndex + 1);
        }
        return false;
    }
}

to be continued...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呛踊,一起剝皮案震驚了整個(gè)濱河市砾淌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谭网,老刑警劉巖汪厨,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異愉择,居然都是意外死亡劫乱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門锥涕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)衷戈,“玉大人,你說(shuō)我怎么就攤上這事层坠≈掣荆” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵破花,是天一觀的道長(zhǎng)谦趣。 經(jīng)常有香客問我,道長(zhǎng)旧乞,這世上最難降的妖魔是什么蔚润? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮尺栖,結(jié)果婚禮上嫡纠,老公的妹妹穿的比我還像新娘。我一直安慰自己延赌,他們只是感情好除盏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挫以,像睡著了一般者蠕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上掐松,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天踱侣,我揣著相機(jī)與錄音粪小,去河邊找鬼。 笑死抡句,一個(gè)胖子當(dāng)著我的面吹牛探膊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播待榔,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼逞壁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了锐锣?” 一聲冷哼從身側(cè)響起腌闯,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雕憔,沒想到半個(gè)月后姿骏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡橘茉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年工腋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姨丈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畅卓。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蟋恬,靈堂內(nèi)的尸體忽然破棺而出翁潘,到底是詐尸還是另有隱情,我是刑警寧澤歼争,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布拜马,位于F島的核電站,受9級(jí)特大地震影響沐绒,放射性物質(zhì)發(fā)生泄漏俩莽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一乔遮、第九天 我趴在偏房一處隱蔽的房頂上張望扮超。 院中可真熱鬧,春花似錦蹋肮、人聲如沸出刷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)馁龟。三九已至,卻和暖如春漆魔,著一層夾襖步出監(jiān)牢的瞬間坷檩,已是汗流浹背却音。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留矢炼,地道東北人僧家。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像裸删,于是被迫代替她去往敵國(guó)和親八拱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1. 需要實(shí)現(xiàn)的功能 照片小圖排列顯示涯塔,點(diǎn)擊任意一張圖片可以切換成大圖肌稻。實(shí)現(xiàn)思路:根視圖中顯示小圖,用滾動(dòng)視圖控制...
    yz_wang閱讀 461評(píng)論 0 1
  • 切片slice 本身并不是數(shù)組匕荸,它指向底層的數(shù)組 作為變長(zhǎng)數(shù)組的替代方案爹谭,可關(guān)聯(lián)底層數(shù)組的局部或全部 數(shù)據(jù)類型為引...
    kaxi4it閱讀 509評(píng)論 0 0
  • 1.ReactiveCocoa簡(jiǎn)介 ReactiveCocoa(簡(jiǎn)稱為RAC),是由Github開源的一個(gè)應(yīng)用于i...
    葉君臣閱讀 1,611評(píng)論 0 1
  • p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo...
    灰客閱讀 421評(píng)論 0 0
  • 馬德華“在我眼中,楊潔既是父親榛搔,也是母親诺凡,更是我的老師〖螅” 王伯昭“楊導(dǎo)說(shuō)腹泌,我要知道你要這么多錢,我早就開了你尔觉×垢ぃ”...
    魚樂圈沒有圈閱讀 873評(píng)論 0 7