剑指offer-java(2)

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

import java.util.ArrayList;
import java.util.*;
public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
      LinkedList<Integer> stack=new LinkedList<Integer>();
      if(pushA.length==0||popA.length==0)
          return false;
      int j=0;
      for(int i=0;i<pushA.length;i++){
          stack.push(pushA[i));
          while(j<pushA.length&& stack.peek()==popA[j]){
                stack.pop();
                j++;
          }
      }
      return stack.isEmpty();
    }
}

(2)从上往下打印二叉树
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
import java.util.*;
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        //层次遍历,借助一个队列来实现
        ArrayList<Integer> list=new ArrayList<Integer>();
        LinkedList<Integer> queue=new LinkedList<Integer>();
        if(root==null)
            return list;
        queue.offer(root);
        while(queue!=null){
        TreeNode node=queue.poll();
        if(node.left!=null)         
            queue.offer(root.left);
        if(node.right!=null)
            queue.offer(root.right);
        list.add(node.val);
        }
        return list;    
    }
}

3,二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        //二叉搜索树,后序遍历,即最后一个节点为根节点。且左子树小于根节点,右子树大于根节点的值
        if(sequence.length==0)
            return false;
    return VerifySquenceOfBST(sequence,0,sequence.length-1);
    }
    public boolean VerifySquenceOfBST(int[] sequence,int start,int end){
        if(end<=start)
            return true;
        int i=start;
        for(;i<end;i++){
            if(sequence[i]>sequence[end]){
                break;
            }
        }
        for(int j=i;j<end;j++){
            if(sequence[j]<sequence[end])   
                return false;
        }
        return VerifySquenceOfBST(sequence,start,i-1)&VerifySquenceOfBST(sequence,i,end-1);
    }
}

4,二叉树中和为某一值的路径
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        ArrayList<ArrayList<Integer>> pathList=new ArrayList<ArrayList<Integer>>();
        if(root==null)
            return ;
        LinkedList<Integer>    stack=new LinkedList<Integer>();
        findpath(root,target,stack,pathList);
        return pathList;
    }
    public void findpath(TreeNode root,int target,LinkedList<Integer> stack,ArrayList<ArrayList<Integer>> pathList){
        if(root==null)
            return;
        if(root.left==null&&root.right==null){
            ArrayList<Integer> list=new ArrayList<Integer>();
            for(int i: stack){
                list.add(new Integer(i));
            }
            list.add(new Integer(root.val));
            pathList.add(list);
    }
    }else{
        stack.add(new Integer(root.val));
        findpath(root.left,target-root.val,stack,pathList);
        findpath(root.right,target-root.val,stack,pathList);
        stack.remove(stack.size()-1);
    }
}

5,复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。

/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
public class Solution{
    public RandomListNode Clone(RandomListNode pHead){
        if(pHead==null)
            return null;
        RandomListNode head=new RandomListNode(pHead.label);
        RandomListNode and=head;
        if(pHead.random!=null){
            head.random=new RandomListNode (pHead.random.label);
        }
        while(pHead.next!=null){
            pHead=pHead.next;
            head.next=new RandomListNode (pHead.label);
            if(pHead.random!=null){
                head.next.random=new RandomListNode (pHead.random.label);
            }
            head=head.next;
        }
        return and;
    }
}

6,二叉搜索树与双向链表
输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表,要求不能创建任何新的节点,只能调整树中节点指针的指向。

//二叉排序树-左子树比根节点值小,右子树比根节点值大
public class Solution{
    public TreeNode Convert(TreeNode pRootOfTree){
        if(pRootOfTree==null)
            return null;
        if(pRootOfTree.left==null&&pRootOfTree.right==null)
            return pRootOfTree;
        TreeNode left=Convert(pRootOfTree.left);
        TreeNode p=left;
        while(p!=null&&p.right!=null)
            p=p.right;
        if(left!=null){
            p.right=pRootOfTree;
            pRootOfTree.left=p;
        }

        TreeNode right=Convert(pRootOfTree.right);
        if(right!=null){
            pRootOfTree.right=right;
            right.left=pRootOfTree;
        }
        return left!=null?left:pRootOfTree;
    }
}

7,字符串的排列
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 结果请按字母顺序输出。

import java.util.*;
public class Solution{
    public ArrayList<String> Permutation(String str){
        ArrayList<String> list=new ArrayList<String>();
        if(str==null||str.length()==0)
            return list;
        char[] c=str.toCharArray();
        TreeSet<String> result=new TreeSet<String>();
        Permutation(c,0,result);
        list.addAll(result);
        return list;
    }
    public void Permutation(char[] c,int begin,TreeSet<String> result){
        if(c==null||c.length==0||begin<0||begin>c.length-1)
            return;
        if(begin==c.length-1)
            result.add(String.valueOf(c));
        else{
                for(int i=begin;i<c.length;i++){
                    swap(c,begin,i);
                    Permutation(c,begin+1,result);
                    swap(c,begin,i);
                }
            }
    }
    public void swap(char[] c,int begin, int i){
        char tmp=c[begin];
        c[begin]=c[i];
        c[i]=tmp;
    }
}

8,数组中出现次数超过一半的数字

public class Solution{
    public int MoreThanHalfNum(int[] array){
        if(array==null||array.length==0)
            return 0;
        int count=0;
        int mid=array[(array.length-1)/2];
        for(int i: array){
            if(i==mid)
                count++;
        }
        if(array.length<count*2)
            return mid;
        else
            return 0;
    }
}

9,最小的K个数

import java.util.*;
public class Solution{
    public ArrayList<Integer> getNumber(int[] input,int k){
        ArrayList<Integer> list=new ArrayList<Integer>();
        if(input==null||input.length==0||input.length<k)
            return list;
        Arrays.sort(input);
        for(int i=0;i<k;i++){
            list.add(input[i]);
        }
        return list;
    }
}

10,连续子数组的最大和

import java.util.*;
public class Solution{
    public int findSumOfSubArray(int[] array){
        List<Integer> list=new ArrayList<Integer>();
        if(array.length==0||array==null)
            return 0;
        for(int i=0;i<array.length;i++){
            int sum=0;
            for(int j=i;j<array.length;j++){
                sum+=array[j];
                list.add(sum);
            }
        }
        Collections.sort(list);
        return list.get(list.size()-1);
    }
}

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

import java.util.*;
public class Solution{
    public int NumberOfBetween1AndN(int n){
        int i=countNum(n);
        return i;
    }
    public int countNum(int n){
        if(n==0)
            return 0;
        if(n<10)
            return 1;
        int len=new Integer(n).toString().length();
        int first;
        int count=0;
        for(len--;len>=0;len--){
            first=(int)(n/Math.pow(10,len));
            if(len==0&&first!=0)
                return ++count;
            else if(len==0)
                return count;
            if(first>1)
                count+=first*getCount(len)+getCount2(len);
            else if(first==1)
                count+=n%getCount2(len)+1+first*getCount(len);
            n=(int)(n%getCount(len));
        }
        return count;
    }
    public int getCount(int len){
        return len*(int)(Math.pow(10,len-1));
    }
    public int getCount2(int len){
        return (int)Math.pow(10,len);
    }
}

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

import java.util.*;
public class Solution{
    public String PrintMinNumber(int[] numbers){
        ArrayList<Integer> list=new ArrayList<Integer>();
        String s="";
        for(int i=0;i<numbers.length;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 j: list){
            s+=j;
        }
        return s;
    }
}

13,丑数
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数

import java.util.*;
public class Solution{
    public int GetUglyNumber(int index){
        if(index==1)
            return 1;
        if(index==0)
            return 0;
        List<Integer> list=new ArrayList<Integer>();
        list.add(1);
        int i2=0,i3=0,i5=0;
        for(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);
    }
}

第一个只出现一次的字符位置
在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符的位置。若为空串,返回-1。位置索引从0开始

import java.util.*;
public class Solution{
    public int firstNotRepeatingChar(String str){
        if(str==null||str.length()==0)
            return -1;
        for(int i=0;i<str.length();i++){
            if(str.length()-str.replaceAll(str.charAt(i)+"","").toString().length()==1)
            return i;
        }
        return -1;
    }
}

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

public class Solution{
    public int InversePairs(int[] array){
        int count=0;
        for(int i=0;i<array.length;i++){
            for(int j=i+1;j<array.length;j++){
                if(array[i]>array[j])   
                    count++;
            }
        }
        return count;
    }
}

输入两个链表,找出它们的第一个公共结点。

import java.util.*;
public class Solution{
    public ListNode findFirstCommonNode(ListNode pHead1,ListNode pHead2){
        if(pHead1==null||pHead2==null)
            return null;
        int count1=0;
        ListNode p1=pHead1;
        while(p1!=null){
            p1=p1.next;
            count1++;
        }
        int count2=0;
        ListNode p2=pHead2;
        while(p2!=null){
            p2=p2.next;
            count2++;   
        }
        //分别计算pHead1和pHead2两个链表的长度,然后计算出长度差
        int flag=count1-count2;
        if(flag>0){
            while(flag>0){
                pHead1=pHead1.next;
                flag--;
            }
            while(pHead1!=pHead2){
                pHead1=pHead1.next;
                pHead2=pHead2.next;
            }
            return pHead1;
        }
        if(flag<=0){
            while(flag<0){
                pHead2=pHead2.next;
                flag++;
            }
            while(pHead1!=pHead2){
                pHead1=pHead1.next;
                pHead2=pHead2.next;
            }
            return pHead1;
        }
        return null;
    }
}

统计一个数字在排序数组中出现的次数。
方法一:

public class Solution{
    public int getNumber(int[] array,int k){
        int count=0;
        for(int i=0;i<array.length;i++){
            if(array[i]==k)
                count++;
        }
        return count;
    }
}

方法二:要求在排序的数组或部分排序的数组中查找一个数字或者统计某个数字的出现次数,都可以尝试使用二分查找法。

public class Solution{
    public int getNumber(int[] array,int k){
        if(array.length==0)
            return 0;
        int low=0;
        int high=array.length-1;
        int mid=(low+high)/2;
        int count=0;
        while(low<high){
            mid=(low+high)/2;
            if(array[mid]>k){
                high=mid-1;
            }else if(array[mid]<k){
                low=mid+1;
            }else{
                count=1;
                int temp=mid-1;
                while(temp>=0&&array[temp]==array[mid]){
                    count++;
                    temp--;
                }
                temp=mid+1;
                while(temp<array.length&&array[temp]==array[mid]){
                    count++;
                    temp++;
                }
                break;
            }
        }
        return count;
    }
}

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

public class Solution{
    public int TreeDepth(TreeNode root){
        if(root==null)
            return 0;
        int nLeft=TreeDepth(root.left);
        int nRight=TreeDepth(root.right);
        return nLeft>nRight?(nLeft+1):(nRight+1);
    }
}

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

首先了解什么是平衡二叉树: 
平衡二叉树:左右子树的深度差不超过1
import java.util.*;
public class Solution{
    public boolean isBalanced(TreeNode root){
        if(root==null)
            return true;
        if(Math.abs(getHight(root.left)-getHeight(root.right))>1)
            return false;
        return isBalanced(root.left)&isBalanced(root.right);
    }
    public int getHeight(TreeNode root){
        if(root==null)
            return 0;
        return Math.max(getHeight(root.left),getHeight(root.right));
    }
}

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

import java.util.*;
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution{
    public void findNumsAppearOnce(int[] array,int num1[],int num2[]){
        if(array.length<2){
            num1[0]=0;
            num2[0]=0;
            return;
        }
        if(array.length==2||array[0]!=array[1]){
            num1[0]=array[0];
            num2[0]=array[1];
        }
        for(int i=0;i<array.length;i++){
            for(int j=i+1;j<array.length;j++){
                if(array[i]^array[j]==0)
                    array[i]=array[j]=0;
            }
        }
        List<Integer> list=new ArrayList<Integer>();
        for(int i=0;i<array.length;i++){
            if(array[i]!=0)
                list.add(array[i]);
        }
        num1[0]=list.get(0);
        num2[0]=list.get(1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值