剑指offer练习

1.题目描述

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 
public class Solution {
    public boolean Find(int target, int [][] array) {
        int row = 0;
        int column = array[0].length-1;
        while(row<array.length && column>=0){
            if(array[row][column]==target)
                return true;
            if(array[row][column]>target)
                column--;
            else
                row++;
        }
        return false;
    }
}

2.题目描述

请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
public static String replaceSpace(StringBuffer str) {
        StringBuffer sb = new StringBuffer();
        String tmp = new String(str);
        for (int i = 0; i < tmp.length(); i++) {
            if(tmp.charAt(i) == ' ')
                sb.append("%20");
            else
                sb.append(tmp.charAt(i));
                    
        }
        return new String(sb);
    }

3.题目描述

输入一个链表,从尾到头打印链表每个节点的值。
package com.lxc.tet;

import java.util.ArrayList;
import java.util.Stack;

public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        Stack<ListNode> stack = new Stack<ListNode>();
        while (listNode != null) {
            stack.push(listNode);
            listNode = listNode.next;
        }
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        while (!stack.isEmpty())
            arrayList.add(stack.pop().val);
        return arrayList;
    }
}

class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

4.题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
import java.util.Arrays;

public class Solution {
    public BinaryTreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre == null||in == null)
            return null;
        //新建二叉树根节点
        BinaryTreeNode root = new BinaryTreeNode();
        //遍历中序遍历
        for (int i = 0; i < in.length; i++) {
            //如果当前元素等于前序遍历的第一个元素
            if(in[i] == pre[0]){
                root.val = in[i];
                System.out.println(root.val);
                root.leftNode = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1),Arrays.copyOfRange(in, 0, i));
                root.rightNode = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length),Arrays.copyOfRange(in, i+1, in.length));
            }
        }
        return root;
    }
}
class BinaryTreeNode {
    int val;
    BinaryTreeNode leftNode;
    BinaryTreeNode rightNode;
}

5.题目描述

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
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.isEmpty()){
            while(!stack1.isEmpty())
                stack2.push(stack1.pop());
        }
        return stack2.pop();
    }
}

7.题目描述

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。

n<=39,在数学上,斐波纳契数列以如下被以 递归的方法定义:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)

递归法:

public class Solution {
    public int fibonacci(int n) {
        if(n==0)
            return 0;
        if(n==1)
            return 1;
        return fibonacci(n-1)+fibonacci(n-2);
    }
}

 迭代法:(动态规划)

public int Fibonacci(int n) {
    int preOne = 0;
    int preTwo = 1;
    int result = 0;
    if(n==0)
        return preOne;
    if(n==1)
        return preTwo;
    for(int i=2;i<=n;i++){
        result = preOne+preTwo;
        preOne = preTwo;
        preTwo = result;
    }
    return result;
} 

8.题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
public class Solution {
    public int NumberOf1(int n) {
        int count = 0;
        while(n!=0){
            count++;
            n=n&(n-1);
        }
        return count;
    }
}

9.题目描述

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
public class Solution {
    public double Power(double base, int exponent) {
        if(exponent==0)
            return 1;
        if(exponent==1)
            return base;
        double result=1.0;
        int len = exponent<0?-exponent:exponent;
        for(int i=0;i<len;i++)
            result*=base;
        return exponent<0?1.0/result:result;
  }
}

10.题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
public int JumpFloor(int target) {
        if(target<=0)
            return 0;
        if(target==1)
            return 1;
        if(target==2)
            return 2;
        int result=0;
        int preOne=1;
        int preTwo=2;
        for(int i=2;i<target;i++){
            result=preOne+preTwo;
            preOne=preTwo;
            preTwo=result;
        }
        return result;    
    }

11.题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
//跳到n级有2n-1种跳法
public
class Solution { public int JumpFloorII(int target) { if(target==0) return 0; if(target==1) return 1; int result=1; for(int i=1;i<target;i++) result*=2; return result; } }

 或者:

public int JumpFloorII(int target) {
    return 1<<(target-1);
}

12.题目描述

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
public class Solution {
    public int RectCover(int target) {
        if(target==0)
            return 0;
        if(target==1)
            return 1;
        int result = 0;
        int one = 0;
        int two = 1;
        for(int i=0;i<target;i++){
            result=one+two;
            one=two;
            two=result;
        }
        return result;
    }
}

13.题目描述

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
public class Solution {
    public void reOrderArray(int [] array) {
        int temp=0;
        for(int i=0;i<array.length-1;i++){
            for(int j=0;j<array.length-1-i;j++){
               if(array[j+1]%2==1 && array[j]%2==0){
                    temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;              
                }    
            }                        
        }
    }
}

14.题目描述

输入一个链表,输出该链表中倒数第k个结点。
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(head==null||k==0)
            return null;
        ListNode p1=head;
        ListNode p2=null;
        for(int i=0;i<k-1;++i){
            if(p1.next!=null)
                p1=p1.next;
            else
                return null;
        }
        p2=head;
        while(p1.next!=null){     
            p1=p1.next;
            p2=p2.next;
        }
        return p2;
    }
}
class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}

15.题目描述

输入一个链表,反转链表后,输出链表的所有元素。
public class Solution {
    public ListNode ReverseList(ListNode head) {
        if(head==null)
            return null;
        ListNode temp=null;
        ListNode pre=null;
        ListNode current=head;
        ListNode reverse=null;
        while(current!=null){
            temp=current.next;
            current.next=pre;
            pre=current;
            if(temp==null)
                reverse=current;
            current=temp;
        }
        return reverse;
    }
}
class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}

16.题目描述

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        if(list1==null)
            return list2;
        if(list2==null)
            return list1;
        ListNode list3 = null;
        if(list1.val<list2.val){
            list3=list1;
            list3.next=Merge(list1.next,list2);
        }else{
            list3=list2;
            list3.next=Merge(list1,list2.next);
        }  
        return list3;
    }
}
class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}

17.题目描述

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
public class Solution {
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        boolean result=false;
        if(root1!=null && root2!=null){
            if(root1.val==root2.val){
                result=doesTree1HaveTreee2(root1,root2);
                if(!result)
                    result=HasSubtree(root1.left,root2);
                if(!result)
                    result=HasSubtree(root1.right,root2);
            }
        }
        return result;
    }
    boolean doesTree1HaveTreee2(TreeNode root1,TreeNode root2){
        if(root2==null)
            return true;
        if(root1==null)
            return false;
        if(root1.val!=root2.val)
            return false;
        return doesTree1HaveTreee2(root1.left,root2.left) && doesTree1HaveTreee2(root1.right,root2.right);
    }
}
class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}

18.题目描述

操作给定的二叉树,将其变换为源二叉树的镜像。
import java.util.Stack;
public class Solution {
    public void Mirror(TreeNode root) {
        if(root==null || (root.left==null && root.right==null))
            root=null;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode temp = null;
        while(root!=null || !stack.isEmpty()){
            while(root!=null){
                temp=root.left;
                root.left=root.right;
                root.right=temp;
                stack.push(root);
                root=root.left;
            }
            root=stack.pop();
            root=root.right;
        }
    }
}
class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}

19.题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        int row = matrix.length;
        int col = matrix[0].length;
        if(row==0 || col==0)
            return result;
        int layers = (Math.min(row,col)-1)/2+1;
        for(int i=0;i<layers;i++){
            for(int k=i;k<col-i;k++)
                result.add(matrix[i][k]);
            for(int j=i+1;j<row-i;j++)
                result.add(matrix[j][col-i-1]);
            for(int k=col-i-2;(k>=i)&&(row-i-1!=i);k--)
                result.add(matrix[row-i-1][k]);
            for(int j=row-i-2;(j>i)&&(col-i-1!=i);j--)
                result.add(matrix[j][i]);
        }
        return result;
    }
}

20.题目描述

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
import java.util.Stack;

public class Solution {

    Stack<Integer> dataStack = new Stack<Integer>();
    Stack<Integer> minStack = new Stack<Integer>();
    
    public void push(int node) {
        dataStack.push(node);
        if(minStack.isEmpty()||node<minStack.peek())
            minStack.push(node);
        else
            minStack.push(minStack.peek());
    }
    
    public void pop() {
        minStack.pop();
        dataStack.pop();
    }
    
    public int top() {
        return dataStack.peek();
    }
    
    public int min() {
        return minStack.peek();
    }
}

21.题目描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
import java.util.Stack;

public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        if(pushA.length==0||popA.length==0)
            return false;
        Stack<Integer> stack = new Stack<Integer>();
        int point=0;
        for(int i=0;i<pushA.length;i++){
            stack.push(pushA[i]);
            while(!stack.empty()&&stack.peek()==popA[point]){
                stack.pop();
                point++;
            }
        }
        return stack.empty();
    }
}

22.题目描述

从上往下打印出二叉树的每个节点,同层节点从左至右打印。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class Solution { public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) { ArrayList<Integer> list = new ArrayList<Integer>(); if(root==null) return list; Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); while(!queue.isEmpty()){ TreeNode treeNode = queue.poll(); if(treeNode.left!=null) queue.add(treeNode.left); if(treeNode.right!=null) queue.add(treeNode.right); list.add(treeNode.val); } return list; } } class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } }

23.题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出true,否则输出false。假设输入的数组的任意两个数字都互不相同。
public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        int len = sequence.length;
        if(len==0)
            return false;
        int i = 0;
        while(--len!=0){
            while(sequence[i]<sequence[len]) i++;
            while(sequence[i]>sequence[len]) i++;
            if(i<len)
                return false;
            i = 0;
        }
        return true;
    }
}

24.题目描述

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
public class Solution {
    public ListNode deleteDuplication(ListNode pHead){
        if(pHead==null || pHead.next==null)
            return pHead;
        if(pHead.val==pHead.next.val){
            ListNode pNode = pHead.next;
            while(pNode!=null && pNode.val==pHead.val)
                pNode=pNode.next;
            return deleteDuplication(pNode);
        }else{
            pHead.next = deleteDuplication(pHead.next);
            return pHead;
        }       
    }
}
class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

25.题目描述

输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
public class Solution {
    private ArrayList<ArrayList<Integer>> listAll = new ArrayList<ArrayList<Integer>>();
    private ArrayList<Integer> list = new ArrayList<Integer>();
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        if(root==null)
            return listAll;
        list.add(root.val);
        target -= root.val;
        if(target==0 && root.left==null && root.right==null)
            listAll.add(new ArrayList<Integer>(list));
        FindPath(root.left,target);
        FindPath(root.right,target);
        list.remove(list.size()-1);
        return listAll;
    }
}
class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}

 26.约瑟夫环问题

package com.lxc.tet;

public class LastRemain {
    public static void main(String[] args) {
        System.out.println(lastRemaining(5,3));
    }

    public static int lastRemaining(int n,int m){
        int last=0;
        for (int i = 2; i <=n; i++) {
            last=(last+m)%i;
        }
        return last;
    }
}

27.题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
public class Solution {
    public RandomListNode Clone(RandomListNode pHead){
        if(pHead == null)
            return null;
        RandomListNode head = new RandomListNode(pHead.label);
        RandomListNode temp = head;
        while(pHead.next!=null){
            temp.next = new RandomListNode(pHead.next.label);
            if(pHead.random!=null)
                temp.random = new RandomListNode(pHead.random.label);
            pHead = pHead.next;
            temp = temp.next;
        }
        return head;
    }
}
class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

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

28.题目描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
public class Solution {
    public TreeNode Convert(TreeNode root) {
        if(root==null)
            return null;
        if(root.left==null && root.right==null)
            return root;
        TreeNode left = Convert(root.left);
        TreeNode p = left;
        while(p!=null && p.right!=null)
            p = p.right;
        if(left!=null){
            p.right = root;
            root.left = p;
        }
        TreeNode right = Convert(root.right);
        if(right!=null){
            root.right = right;
            right.left = root;
        }
        return left!=null?left:root;
    }
}
class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}

29.题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
import java.util.ArrayList;
import java.util.Collections;
public class Solution {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> list = new ArrayList<String>();
        if (str.length() == 0 || str == null)
            return list;
        char[] c = str.toCharArray();
        helper(list,0,c);
        Collections.sort(list);
        return list;
    }

    public void helper(ArrayList<String> list,int index,char[] c) {
        if (index == c.length - 1)
            list.add(new String(c));
        for (int i = index; i < c.length; i++) {
            if (i == index || c[index] != c[i]) {
                swap(c, index, i);
                helper(list, index + 1, c);
                swap(c, index, i);
            }
        }
    }

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

30.题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
import java.util.Map;
import java.util.HashMap;
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        int halfLen = array.length/2;
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        for(int i: array){
            Integer count = map.get(i);
            if(count!=null)
                count++;
            else
                count=1;
            map.put(i, count);
        }
        for (Integer key : map.keySet()) {
            if(map.get(key)>halfLen)
                return key;
        }
        return 0;
    }
}

31.题目描述

整数中1出现的次数(从1到n整数中1出现的次数)

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int count=0;
        for(int i=1;i<=n;i*=10){
            int a=n/i,b=n%i;
            if(a%10==0)
                count+=a/10*i;
            else if(a%10==1)
                count+=(a/10*i)+(b+1);
            else
                count+=(a/10+1)*i;
        }
        return count;
    }
}

32.题目描述

连续子数组的最大和(包含负数)

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        if(array.length==0)
            return 0;
        int currentSum=0;
        int greatestSum=0x80000000;
        for(int i=0;i<array.length;i++){
            if(currentSum<=0)
                currentSum=array[i];
            else
                currentSum+=array[i];
            if(currentSum>greatestSum)
                greatestSum=currentSum;
        }
        return greatestSum;
    }
}

33.题目描述

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        if(numbers==null||numbers.length==0)
            return "";
        int len = numbers.length;
        String[] str = new String[len];
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<len;i++)
            str[i]=Integer.toString(numbers[i]);
     //按自定义的比较规则进行排序 Arrays.sort(str,
new Comparator<String>(){ public int compare(String s1,String s2){ String c1 = s1+s2; String c2 = s2+s1; return c1.compareTo(c2); } }); for(int i=0;i<len;i++) sb.append(str[i]); return sb.toString(); } }

34.题目描述

把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
import java.util.ArrayList;
public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index<=0)
            return 0;
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        int i2=0,i3=0,i5=0;
        while(list.size()<index){
            int n2=list.get(i2)*2;
            int n3=list.get(i3)*3;
            int n5=list.get(i5)*5;
            int min=Math.min(n2,Math.min(n3,n5));
            list.add(min);
            if(min==n2)
                i2++;
            if(min==n3)
                i3++;
            if(min==n5)
                i5++;
        }
        return list.get(list.size()-1);
    }
}

35.题目描述

第一个只出现一次的字符:在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置
import java.util.*;
public class Solution {
    public int FirstNotRepeatingChar(String str) {
        Map<Character,Integer> map = new LinkedHashMap<Character,Integer>();
        for(int i=0;i<str.length();i++){
            char c = str.charAt(i);
            Integer num = map.get(c);
            if(num==null)
                num=1;
            else
                num++;
            map.put(c,num);
        }
        for(char c:map.keySet()){
            if(map.get(c)==1)
                return str.indexOf(c);
        }
         return -1;
    }
}

或者:

import java.util.*;
public class Solution {
    public int FirstNotRepeatingChar(String str) {
        Map<Character,Integer> map = new HashMap<Character,Integer>();
        for(int i=0;i<str.length();i++){
            char c = str.charAt(i);
            Integer num = map.get(c);
            if(num==null)
                num=1;
            else
                num++;
            map.put(c,num);
        }
        for(int i=0;i<str.length();i++){
            char c=str.charAt(i);
            if(map.get(c)==1)
                return i;
        }
        return -1;
    }
}

36.题目描述(数组中的逆序对)

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
public class Solution {
    public int InversePairs(int [] array) {
        if(array==null)
            return 0;
        int[] copy = array.clone();
        int len = array.length-1;
        return mergeSort(array,copy,0,len);
    }
    private int mergeSort(int[] array,int[] copy,int low,int high){
        if(low==high)
            return 0;
        int mid = (low+high)>>1;
        int left = mergeSort(array,copy,low,mid)%1000000007;
        int right = mergeSort(array,copy,mid+1,high)%1000000007;
        int count=0;
        int i=mid;
        int j=high;
        int locCopy=high;
        while(i>=low&&j>mid){
            if(array[i]>array[j]){
                count+=j-mid;
                copy[locCopy--]=array[i--];
                if(count>=1000000007)
                    count%=1000000007;
            }else
                copy[locCopy--]=array[j--];
        }
        for(;i>=low;i--)
            copy[locCopy--]=array[i];
        for(;j>mid;j--)
            copy[locCopy--]=array[j];
        for(int k=low;k<=high;k++)
            array[k]=copy[k];
        return (left+right+count)%1000000007;
    }
}

37.题目描述

输入两个链表,找出它们的第一个公共结点。
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        int len1 = getLength(pHead1);
        int len2 = getLength(pHead2);
        ListNode longer = null;
        ListNode shorter = null;
        int dif = 0;
        if(len1>len2){
            longer = pHead1;
            shorter = pHead2;
            dif = len1-len2;
        }else{
            longer = pHead2;
            shorter = pHead1;
            dif = len2-len1;
        }
        for(int i=0;i<dif;i++)
            longer = longer.next;
        while(longer!=null && shorter!=null && longer!=shorter){
            longer = longer.next;
            shorter = shorter.next;
        }
        return longer;
    }
    private int getLength(ListNode head){
        int result=0;
        if(head==null)
            return result;
        ListNode p = head;
        while(p!=null){
            p=p.next;
            result ++;
        }
        return result;
    }
}
class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

38.题目描述

统计一个数字在排序数组中出现的次数。
public class Solution {
    public int GetNumberOfK(int [] array , int k) {
       int number=0;
       if(array!=null){
           int first = getFirstIndex(array,k,0,array.length-1);
           int last = getLastIndex(array,k,0,array.length-1);
           if(first>-1 && last>-1)
               number = last-first+1;
       }
        return number;
    }
    private int getFirstIndex(int[] array,int k,int start,int end){
        if(start>end)
            return -1;
        int midIndex = (start+end)>>1;
        int midVal = array[midIndex];
        if(midVal==k){
            if(midIndex>0 && array[midIndex-1]!=k || midIndex==0)
                return midIndex;
            else
                end = midIndex-1;
        }else if(midVal>k)
            end = midIndex-1;
        else
            start = midIndex+1;
        return getFirstIndex(array,k,start,end);
    }
    private int getLastIndex(int[] array,int k,int start,int end){
        if(start>end)
            return -1;
        int midIndex = (start+end)>>1;
        int midVal = array[midIndex];
        if(midVal==k){
            if(midIndex<array.length-1 && array[midIndex+1]!=k || midIndex==array.length-1)
                return midIndex;
            else
                start = midIndex+1;
        }else if(midVal<k)
            start = midIndex+1;
        else
            end = midIndex-1;
        return getLastIndex(array,k,start,end);
    }
}

39.题目描述

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root==null)
            return 0;
        int left = TreeDepth(root.left);
        int right = TreeDepth(root.right);
        return left>right?left+1:right+1;
    }
}
class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}

40.题目描述

输入一棵二叉树,判断该二叉树是否是平衡二叉树。
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root==null)
            return true;
        int left=depth(root.left);
        int right = depth(root.right);
        int dif = left-right;
        if(dif>1 || dif<-1)
            return false;
        //return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
        return true;
    }
    private int depth(TreeNode root){
        if(root==null)
            return 0;
        int left=depth(root.left);
        int right = depth(root.right);
        return left>right?left+1:right+1;
    }
}

41.题目描述

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        if(array==null || array.length<=1){
            num1[0]=num2[0]=0;
            return;
        }
        int index=0,sum=0;
        for(int i:array)
            sum^=i;
        for(index=0;index<32;index++){
            if((sum & (1<<index)) !=0)
                break;
        }
        for(int i:array){
            if((i & (1<<index)) !=0)
                num2[0]^=i;
            else
                num1[0]^=i;
        }
    }
}

42.题目描述

 和为S的连续正数序列
import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
        if(sum<3)
            return list;
        int small = 1;
        int big = 2;
        int mid = (1+sum)>>1;
        int curSum = small+big;
        while(small<mid){
            if(curSum==sum)
                list.add(contineNum(small,big));
            while(curSum>sum && small<mid){
                curSum -= small;
                small++;
                if(curSum==sum)
                    list.add(contineNum(small,big));
            }
            big++;
            curSum+=big;
        }
        return list;
    }
    private ArrayList<Integer> contineNum(int small,int big){
        ArrayList<Integer> list = new ArrayList<Integer>();
        for(int i=small;i<=big;i++)
            list.add(i);
        return list;
    }
}

43.题目描述

和为S的两个数字

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if(array==null || array.length<2)
            return list;
        int i = 0,j = array.length-1;
        while(i<j){
            if(array[i]+array[j]==sum){
                list.add(array[i]);
                list.add(array[j]);
                return list;
            }else if(array[i]+array[j]>sum)
                j--;
            else
                i++;
        }
        return list;
    }
}

44.题目描述

 字符串的左旋转操作是把前面若干个移到尾部。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。

public class Solution {
    public String LeftRotateString(String str,int n) {
        if(str == null || n>str.length() || n<0)
            return str;
        String[] splitStr = {str.substring(0,n),str.substring(n,str.length())};
        StringBuffer sb = new StringBuffer();
        for(String s:splitStr)
            sb.append(reverse(s));
        return reverse(sb.toString());
    }
    public String reverse(String str){
        char[] array = str.toCharArray();
        for(int i=0;i<(array.length+1)/2;i++){
            char temp = array[i];
            array[i] = array[array.length-1-i];
            array[array.length-1-i] = temp;
        }
        return String.valueOf(array);
    }
}

45.题目描述

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变,为简单起见,标点符号和普通字母一样处理。例如:输入字符串:"I am a student.",则输出"student. a am I"。

public class Solution {
    public String ReverseSentence(String str) {
        if(str == null || "".equals(str.trim()))
            return str;
        String[] arr = str.split(" ");
        StringBuffer sb = new StringBuffer();
        for(int i = arr.length-1;i>=0;i--)
            sb.append(arr[i]+" ");
        return sb.toString().trim();
    }
}

46.题目描述

从扑克牌中随机抽5张牌,判断是不是顺子,即这5张牌不是连续的。2~10位数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成是任意的数字。

public boolean isContinious(int[] number){
        if(number == null)
            return false;
        Arrays.sort(number);
        int numberZero = 0;
        int numberGap = 0;
        // 统计数组中0的个数
        for (int i = 0; i < number.length && number[i] == 0; i++) {
            numberZero++;
        }
        // 统计数组中间隔的个数
        int small = numberZero;
        int big = small+1;
        while(big<number.length){
            if(number[small] == number[big])
                return false;
            numberGap += number[big]-number[small]-1;
            small = big;
            big++;
        }
        return numberGap>numberZero?false:true;
    }

47.题目描述(圆圈中最后剩下的数字)

0,1,...,n-1这n个数排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。

public class Solution {
    public int LastRemaining_Solution(int n, int m) {
        if(n<1 || m<1)
            return -1;
        int last = 0;
        for(int i=2;i<=n;i++)
            last = (last+m)%i;
        return last;
    }
}

48.题目描述

 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

public class Solution {
    public int Sum_Solution(int n) {
        int sum = n;
        // 递归求和,利用&&短路终止递归,保证&&两边都是布尔型值
        boolean flag = n>0 && (sum += Sum_Solution(n-1))>0;
        return sum;
    }
}

49.题目描述

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

public class Solution {
    public int Add(int num1,int num2) {
        while(num2 != 0){
            int temp = num1 ^ num2;
            num2 = (num1 & num2) << 1;
            num1 = temp;
        }
        return num1;
    }
}
原文地址:https://www.cnblogs.com/lxcmyf/p/8344127.html