Java 剑指offer 21-40题

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

import java.util.*;

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

        }
        return stack.empty();
    }
}

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

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

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

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length ==0) return false;
        return IsTreeBST(sequence, 0, sequence.length-1);
    }

    private boolean IsTreeBST(int[] sequence, int start, int end) {
        if(start>=end) return true;
        int i;
        for (i=start; i < end; i++) {
            if(sequence[i] >sequence[end])
                break;
        }
        for (int j = i; j < end; j++) {
            if(sequence[j] < sequence[end])
                return false;
        }
        return IsTreeBST(sequence,start,i-1) && IsTreeBST(sequence,i,end-1);
    }
}

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

import java.util.ArrayList;
public class Solution {
    public ArrayList<String> Permutation(String str)  {
        ArrayList<String> arr = new ArrayList<>();
        if(str.length() == 0) return arr;
        Check(arr,str,"");
        return arr;
    }

    public void Check(ArrayList<String> arr, String str, String s) {
        if(str.length() == 0){
            if(arr.indexOf(s)==-1){
                arr.add(s);
            };
            return;
        }
        int n=str.length();
        for (int i = 0; i < n; i++) {
            String tmp =str.substring(0,i)+str.substring(i+1,n);
            Check(arr,tmp,s+str.charAt(i));
        }
    }
}

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

import java.util.*;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
            ArrayList<Integer> result = new ArrayList<>();
            int length = input.length;
            if(k > length || k == 0){
                return result;
            }
            PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, Comparator.reverseOrder());
            for (int i = 0; i < length; i++) {
                if (maxHeap.size() != k) {
                    maxHeap.add(input[i]);
                }
                else if (maxHeap.peek() > input[i]) {
                    maxHeap.poll();
                    maxHeap.add(input[i]);
                }
            }
            for (Integer integer : maxHeap) {
                result.add(integer);
            }
            return result;
        }
}

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

import java.util.*;
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        if (array.length == 0) return 0;
        Arrays.sort(array);
        int x = array[array.length/2];
        int k=0;
        for (int i = 0; i < array.length; i++) {
            if(array[i] == x) k++;
        }
        if(k>array.length/2) return x;
        else return 0;
    }
}
查找中间的一个

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1) 

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        int max = array[0];
        int b = array[0];
        for (int i = 1; i < array.length; i++) {
            max = Math.max(max+array[i],array[i]);
            b = Math.max(b,max);
        }
        return b;
    }
}

在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

import java.util.*;
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;
    }
}

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

先让长的走两个链表的差值,然后在一起走

---------------------------------------------------------------------

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

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

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

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+1)>(right+1)?left+1:right+1;
    }
}
或
public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root == null) return 0;
        return TreeDepth(root.left)>TreeDepth(root.right)?TreeDepth(root.left)+1:TreeDepth(root.right)+1;
    }
}

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

public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root== null) return true;
        if((Math.abs(Check(root.left) - Check(root.right)) > 1)) return false;
        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
    public int Check(TreeNode root){
        if(root == null ) return 0;
        return Math.max(Check(root.left),Check(root.right))+1;
    }
}

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer> > result = new ArrayList<>();
        if(sum == 0) return result;
        int begin = 1;
        int end = 2;
        while(begin < end){
            int sum_temp = (begin+end)*(end-begin+1)/2;
            if(sum_temp == sum) {
                ArrayList<Integer> list = new ArrayList<>();
                for(int i = begin;i<=end;i++){
                    list.add(i);
                }
                end++;
                result.add(list);
            }else if(sum_temp > sum){
                begin++;
            }else{
                end++;
            }
        }
        return result;
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值