算法学习之剑指offer(五)

题目1

题目描述

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

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {       
        if(sequence==null||sequence.length==0)
            return false;
        return check(sequence,0,sequence.length-1);
    }
    
    public boolean check(int [] sequence,int start,int end) {
    	//单个节点的情况
        if((end-start)==0)
            return true;
        int i=end;
        //找到左右子树分界点
        for(;i>=start;i--)
             if(sequence[i]<sequence[end])
        		break;
        if(start>i)//说明全是右子树
            return true;
        //检查左子树里是不是有不符合的	
        for(int j=start;j<=i;j++)
            if(sequence[j]>=sequence[end])
        		return false;
        //不断对左右子树递归检查
        return check(sequence,start,i)&&check(sequence,i+1,end-1);
        
    }
}

题目2

题目描述

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

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 {

	private ArrayList<ArrayList<Integer>> listAll = new ArrayList<ArrayList<Integer>>();
    
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        if(root==null)
            return listAll;
        ArrayList<Integer> list = new ArrayList<Integer>();
       	doFindPath(root,list,target);
        return listAll;
    }
    
     public void doFindPath(TreeNode root,ArrayList<Integer> list,int target) {
         if(root==null)
             return;
     	target -=  root.val;
        list.add(root.val);
        if(root.left==null&&root.right==null&&target==0)
        	listAll.add(list);
         
       	 doFindPath(root.left,new ArrayList<Integer>(list),target);
         doFindPath(root.right,new ArrayList<Integer>(list),target);
         
     }
}
第二次参考他人的代码为:

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 {

	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;
        target -=  root.val;
        list.add(root.val);
        if(root.left==null&&root.right==null&&target==0)
        	listAll.add(new ArrayList<Integer>(list));
        
        FindPath(root.left,target);
        FindPath(root.right,target);
        
        list.remove(list.size()-1);
        
        return listAll;
    }
}
题目3

题目描述

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

/*
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 node = pHead;
        
        while(node!=null){
            RandomListNode new_node = new RandomListNode(node.label);
            new_node.next = node.next;
            node.next = new_node;
            
            node = new_node.next;
        }
        node = pHead;
        while(node!=null){
            
            if(node.random!=null)
            	node.next.random = node.random.next;
            node = node.next.next;
        }
        
        RandomListNode head = pHead.next;
        RandomListNode cirNode = pHead.next;
        node = pHead;
        
       while(node!=null){
           node.next = node.next.next;
           
           if(cirNode.next!=null)
           		cirNode.next = cirNode.next.next;
           
           node = node.next;
           cirNode = cirNode.next;
       }
        
        return head;
    }
}

题目4

题目描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
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;
        }
        if(left!=null)
        	return left;
        else
            return pRootOfTree;
    }
}
题目5

题目描述

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

输入描述:

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。


算法思路:
1)n个元素的全排列=(n-1个元素的全排列)+(另一个元素作为前缀)
2)出口:如果只有一个元素的全排列,则说明已经排完,则输出数组;
3)不断将每个元素放左第一个元素,然后将它作为前缀,并将其余元素继续全排列


import java.util.ArrayList;
import java.util.*;
public class Solution {
    ArrayList<String> list = new ArrayList<String>();
    HashSet<String> hs = new HashSet<String>();
    
    public ArrayList<String> Permutation(String str) {

        if(str==null||str.length()==0)
            return list;
        
        char[] chars = str.toCharArray();
        
        doPermutation(chars,0,str.length()-1);
        list.addAll(hs);
        Collections.sort(list);
        
        return list;
    }
    
    public void doPermutation(char[] chars,int start,int end) {
    	
        if(start==end){
            StringBuilder sb = new StringBuilder();
            for(char c:chars){
                sb.append(c);
            }
            hs.add(sb.toString());
        }else{
            for(int i=start;i<=end;i++){
                swap(chars,start,i);
                doPermutation(chars,start+1,end);
                swap(chars,start,i);
            }
        }
        
    }
    public void swap(char[] chars,int a,int b){
        char tmp = chars[a];
        chars[a] = chars[b];
        chars[b] = tmp;
    }
}

题目6

题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
2种解法:自己用快排然后找中间的数去比较的巨长的解法 + 网上的复杂度仅为O(n)的解法!
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        
        if(array==null)
            return 0;
        sort(array,0,array.length-1);
        
        int index = (array.length)/2;
        int times=0;
        for(int i=0;i<array.length;i++)
            if(array[i]==array[index])
                times++;
    	if(times>index)
            return array[index];
        else
            return 0;
    }
    public void sort(int [] array,int start,int end) {
        if(start>=end)
           return ;
        int p = partition(array,start,end);
        
        sort(array,start,p-1);
        sort(array,p+1,end);
    }
    public int partition(int [] array,int start,int end) {
        int p = start;
        for(int i=start+1;i<=end;i++){
            if(array[start]>array[i]){
                swap(array,++p,i);
            }
        }
        swap(array,p,start);
        return p;
    }
    public void swap(int[] data, int a, int b) {
		int tmp = data[a];
		data[a] = data[b];
		data[b] = tmp;
	}
}
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {

 		int n = array.length;
        if (n == 0) return 0;
         
        int num = array[0], count = 1;
        for (int i = 1; i < n; i++) {
            if (array[i] == num) count++;
            else count--;
            if (count == 0) {
                num = array[i];
                count = 1;
            }
        }
        // Verifying
        count = 0;
        for (int i = 0; i < n; i++) {
            if (array[i] == num) count++;
        }
        if (count * 2 > n) return num;
        return 0;
    }
}




原文地址:https://www.cnblogs.com/chz-blogs/p/9380931.html