剑指offer题目及java实现(2)

1、操作给定的二叉树,将其变换为源二叉树的镜像(照镜子)。 

public class Solution {
    public void Mirror(TreeNode root) {
        if(root==null)
            return ;   
        TreeNode p=root.left;
        root.left=root.right;
        root.right=p;       
        Mirror(root.left);       
        Mirror(root.right); 
    }
}

2、输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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.

public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       if(matrix==null)
           return  null;
        ArrayList list=new ArrayList();
        int left=0;
        int low=matrix.length;
        int cow=matrix[0].length;
        int right=cow-1;
        int top=0;
        int botom=low-1;
        while(left<=right&&top<=botom){
          for(int i=left;i<=right;i++)
              {
              list.add(matrix[top][i]);
          }
            for(int i=top+1;i<=botom;i++){
                list.add(matrix[i][right]);
            }
           if(top!=botom){
               for(int k=right-1;k>=left;k--){
                   list.add(matrix[botom][k]);
               }
           }
           //从下到上
           if(left!=right){
               for(int l=botom-1;l>top;l--){
                   list.add(matrix[l][left]);
               }
           }            
           //下一个正方形矩阵
           top++;left++;right--;botom--;            
        }
        return list;
    }
}

3、定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

import java.util.Stack;
import java.util.Iterator;
public class Solution {
     Stack <Integer> stack=new Stack<Integer>();
    public void push(int node) {
       stack.push(node); 
    } 
    public void pop() {
        int p=stack.pop();     
    } 
    public int top() {    
        return stack.peek();
    }
    public int min() {
        int min=stack.peek();
     Iterator <Integer> it=stack.iterator();
        while(it.hasNext()){
         int n= it.next();
            if(n<min)
            {min=n;
            }
    }
        return min;
}
}

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

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

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

public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> array=new ArrayList<>();
      	if(root==null)
	return array;
	Deque<TreeNode> q=new LinkedList<>();
    q.add(root);
	while(!q.isEmpty()){
		TreeNode t=q.pop();
	array.add(t.val);
	if(t.left!=null)
		q.add(t.left);
	if(t.right!=null)
		q.add(t.right);
	}
	return array;
}
}

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

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length<=0)
            return false;
        int r=sequence[sequence.length-1];
        int i=0;
        for(;i<sequence.length-1;i++){
            if(sequence[i]>r)
                break;
        }
        int j=i;
        for(;j<sequence.length-1;j++){
            if(sequence[j]<r)
                return false;
        }
        boolean left=true;
        boolean right=true;
		if(i>0){
            left=VerifySquenceOfBST(Arrays.copyOfRange(sequence, 0, i));
        }
        if(i<sequence.length-1)
            right=VerifySquenceOfBST(Arrays.copyOfRange(sequence, i, sequence.length-1));
        return (left&&right);
        }
}

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

public class Solution {
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
    ArrayList<ArrayList<Integer>> arr=new ArrayList<ArrayList<Integer>>();
        if(root==null)
            return arr;
        ArrayList<Integer> a1=new ArrayList<Integer>();
        int sum=0;
        pa(root,target,arr,a1,sum);
        return arr;
    }
    public void pa(TreeNode root,int target,ArrayList<ArrayList<Integer>> arr, ArrayList<Integer> a1,int sum){
        if(root==null)
            return ;
        sum+=root.val;        
        if(root.left==null&&root.right==null){
            if(sum==target)
                { a1.add(root.val);
                arr.add(new ArrayList<Integer>(a1));
                a1.remove(a1.size()-1);              
            }
          return ;      
        }  
         a1.add(root.val);
         pa(root.left,target,arr,a1,sum);
        pa(root.right,target,arr,a1,sum);
        a1.remove(a1.size()-1);       
    }
}

7、输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {   
    clone(pHead);
    connectNode(pHead);
    return ReconnectNode(pHead);
    }
    public void clone(RandomListNode pHead){
        RandomListNode p=pHead;
        while(p!=null){
        	RandomListNode clonep=new RandomListNode(0);
            clonep.label=p.label;
            clonep.next=p.next;
            clonep.random=null;
            p.next=clonep;
            p=clonep.next;
        }
    }
  public   void connectNode(RandomListNode pHead){
        RandomListNode p=pHead;
        while(p!=null){
             RandomListNode clonep=p.next;
            if(p.random!=null){
                clonep.random=p.random.next;
            }
            p=clonep.next;
        }
    }
     public RandomListNode ReconnectNode( RandomListNode pHead){
    	 RandomListNode p=pHead;
    	 RandomListNode clonep=null;
    	 RandomListNode cloneNode=null;{
              if(p!=null){
                  clonep=cloneNode=p.next;
                  p.next=cloneNode.next;
                  p=p.next;
              }
              while(p!=null){
                  cloneNode.next=p.next;
                  cloneNode=cloneNode.next;
                  p.next=cloneNode.next;
                  p=p.next;
              }
              return clonep;
          }
     }
    
}

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

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;
		}
}

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



class test { public static void main(String[] args) {} public ArrayList<String> Permutation(String str) { ArrayList<String> res=new ArrayList<String>(); if(str.length()==0||str==null) return res; int n= str.length(); helper(res,0,str.toCharArray()); Collections.sort(res); return res; } public void helper( ArrayList<String> res,int index,char []s) { if(index==s.length-1)res.add(new String(s)); for(int i=index;i<s.length;i++) { if(i==index||s[index]!=s[i]) { swap(s,index,i); helper(res,index+1,s); swap(s,index,i); } } } public void swap(char[]t,int i,int j) { char c=t[i];t[i]=t[j];t[j]=c;} }

10、数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

public class Solution {
public int MoreThanHalfNum_Solution(int [] array) { 
	int len=array.length;
	if(len<1){
		return 0;
	}
	int count=0;
	Arrays.sort(array);
	int num=array[len/2];
	for(int i=0;i<len;i++){
	if(num==array[i])
	count++;
	}
	if(count<=(len/2)){
	num=0;
	}
	return num;
}
}

11、输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> a=new ArrayList<>();
       if(input.length<=0||k>input.length||k==0)
           return a;
        int start=0;
        int end=input.length-1;
        int index=partition(input,start,end);
        while(index!=k-1){
            if(index>k-1){
                end=index-1;
                index= partition(input, start, end); 
            }else{
                start=index+1;
                index= partition(input, start,  end); 
            }
        }
        for(int i=0;i<k;i++){
            a.add(input[i]);
        }
        return a;
    }
    private static int partition(int[] array, int beg, int end) {  
        int first = array[beg];  
        int i = beg, j = end;  
        while (i < j) {  
            while (array[i] <= first && i < end) {  
                i++;  
            }  
            while (array[j] > first && j >= beg) {  
                j--;  
            }  
            if (i < j) {  
                array[i] = array[i] ^ array[j];  
                array[j] = array[i] ^ array[j];  
                array[i] = array[i] ^ array[j];  
            }  
        }  
        if (j != beg) {  
            array[j] = array[beg] ^ array[j];  
            array[beg] = array[beg] ^ array[j];  
            array[j] = array[beg] ^ array[j];  
        }  
        return j;       
}
}

12、连续子数组的最大和

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

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

 public int NumberOf1Between1AndN_Solution(int n) {
        int cout=0;
        while(n>0){
            String s=String.valueOf(n);
            char c[]=s.toCharArray();
            for(int i=0;i<c.length;i++){
                if(c[i]=='1')
                    cout++;
            }
            n--;
        }
        return cout;
        
    }
}

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

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] = String.valueOf(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();
}		
}

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

public class Solution {
    public int GetUglyNumber_Solution(int index) {
	        if(index<=0)
	        return 0;
	        int pugly[]=new int [index];
	        pugly[0]=1;
	       int  nextugly=1;
	       int pugly2=pugly[0];
	       int pugly3=pugly[0];
	       int pugly5=pugly[0];
	       int j1=0;int k1=0;int z1=0;
	        while(nextugly<index){
	        	int min= Min(pugly2*2,pugly3*3,pugly5*5);
	        	pugly[nextugly]=min;
	        	while(pugly2*2<=pugly[nextugly]){
	        		pugly2=pugly[++j1];
	        	}
	        	while(pugly3*3<=pugly[nextugly]){
	        		pugly3=pugly[++k1];
	        	}
	        	while(pugly5*5<=pugly[nextugly]){
	        		pugly5=pugly[++z1];
	        	}
	        	nextugly++;
	        }
	        int ugly=pugly[nextugly-1];
	        return ugly;
	 }
	private int Min(int i, int j, int k) {
		// TODO Auto-generated method stub
		int min=(i<j)?i:j;
		min=(min<k)?min:k;
		return min;
	}
 
}

16、在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符,并返回它的位置

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

17、在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。即输出P%1000000007

public class Solution {
    long count=0;
    public int InversePairs(int [] array)
{   
	if(array==null||array.length==0)
		return 0;
	int[] temp=new int[array.length];
	divid(array,temp,0,array.length-1);
	return (int)(count%1000000007);
}
public void divid(int[]array,int []temp,int low,int high){
	if(low>=high)
		return;
	int mid=(low+high)/2;
	divid(array,temp,low,mid);
	divid(array,temp,mid+1,high);
	merge(array,temp,low,high);
}
public void merge(int[]array,int[]temp,int low,int high){
	int lowend=(low+high)/2;
	int highpos=lowend+1;
	int temppos=low;
	int len=high-low+1;
	while(low<=lowend&&highpos<=high){
		if(array[low]<=array[highpos]){
			temp[temppos++]=array[low++];
		}else{
			count+=(lowend-low+1)%1000000007;
			temp[temppos++]=array[highpos++];
		}
	}
	while(low<=lowend){
		temp[temppos++]=array[low++];
	}
	while(highpos<=high){
		temp[temppos++]=array[highpos++];
	}
	for(int i=len;i>0;i--,high--){
		array[high]=temp[high];
    }
}
}

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

public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        int length1=getlength(pHead1);
       int length2= getlength(pHead2);
       int length=length1-length2;
        ListNode plong=pHead1;
          ListNode qshort=pHead2;  
        if(length2>length1){
            plong=pHead2;
            qshort=pHead1;
             length=length2-length1;
        }
        for(int i=0;i<length;++i){
            plong=plong.next;
        }
        while(plong!=null&&qshort!=null&&plong!=qshort){
            plong=plong.next;
            qshort=qshort.next;
        }
        ListNode p=plong;
        return p;
    }
    public int getlength(ListNode pHead){
        int length=0;
        ListNode p=pHead;
        while(p!=null){
            ++length;
            p=p.next;
        }
        return length;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值