Java联系题

1.求解二叉树的深度

       二叉树深度:从根节点到叶子结点一次经过的结点(含根和叶子结点)形成树的一条路径,最长路径的长度为树的深度(即最长路径上结点的数目)

二叉数的深度求解思路:

  1. 空数的深度为0;
  2. max(左子树最大深度,右子树最大深度)+1
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftLen = TreeDepth(root.left);
        int rightLen = TreeDepth(root.right);
        if(leftLen > rightLen){
            return leftLen + 1;
        }else{
            return rightLen + 1;
        }
    }
}

2.判断一个二叉树是否为平衡二叉数

      平衡二叉树:又称AVL树,它或者是一棵空数,或者是左子树和右子树都是平衡二叉树且左子树和右子树的深度之差的绝对值不超过1.

判断平衡二叉树的思路:

  1. 空树是平衡二叉树;
  2. 求当前结点作为根节点的树的左右子树深度之差的绝对值;
  3. 若当前结点左右子树的深度之差的绝对值大于1,则该树不是平衡二叉树;
  4. 若当前结点左右子树的深度之差的绝对值不大于1,继续判断其左子树和右子树是否是平衡二叉树;
  5. 该树上所有结点作为根节点的树都是平衡二叉树,那么该二叉树就是平衡二叉树
import java.util.*;
public class Solution {
    public int TreeDepth(TreeNode root){
        if(root == null){
            return 0;
        }
        int l = TreeDepth(root.left);
        int r = TreeDepth(root.right);
        return l>r? l+1: r+1;
    }
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null){
            return true;
        }
        int l = TreeDepth(root.left);
        int r = TreeDepth(root.right);
        if(Math.abs(l-r) > 1){
            return false;
        }
        boolean lb = IsBalanced_Solution(root.left);
        boolean rb =IsBalanced_Solution(root.right);
        return lb && rb;
    }
}

3.和为S的联系正数序列

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

import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
        int bound = (int) (Math.ceil((Math.sqrt(8*sum+1)-1)/2));
        if(sum%2 == 0){
            for(int i = 4; i<=bound;i = 2*i){
                ArrayList<Integer> temp = new ArrayList<>();
                if((2*sum)%i==0 && (2*sum/i)%2 == 1){
                    int start = (2*sum/i - 1)/2 - i/2 +1;
                    if(start < 1){
                        break;
                    }
                    for(int k = 0; k < i; k++){
                        temp.add(Integer.valueOf(start+k));
                    }
                    ans.add(temp);
                }
            }
        }else {
        	for(int i = 2; i<= bound; i= i+2) {
        		ArrayList<Integer> temp = new ArrayList<>();
                if((2*sum)%i==0 && (i/2)%2 == 1){
                    int start = (2*sum/i - 1)/2 - i/2 +1;
                    if(start < 1){
                        break;
                    }
                    for(int k = 0; k < i; k++){
                        temp.add(Integer.valueOf(start+k));
                    }
                    ans.add(temp);
                }
        	}
        }
        for(int i = 3;i<=bound ; i = i + 2){
            ArrayList<Integer> temp = new ArrayList<>();
            if(sum%i == 0){
                int start = sum/i - i/2;
                if(start < 1){
                    break;
                }
                for(int k = 0; k < i; k++){
                    temp.add(Integer.valueOf(start+k));
                }
                ans.add(temp);
            }
        }
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        ArrayList<Integer> t = new ArrayList<>();
        while(ans.size() != 0) {
        	t = ans.get(0);
        	for(int n = 1; n < ans.size(); n++) {
        		if(ans.get(n).get(0) < t.get(0)) {
                    	t = ans.get(n);
        		}
        	}
        	result.add(t);
        	ans.remove(t);
        }
        return result;
    }
}

发现自己虽然实现的功能,但是代码太过冗余:下面是借鉴一下其他同学的

1)由于我们要找的是和为S的连续正数序列,因此这个序列是个公差为1的等差数列,而这个序列的中间值代表了平均值的大小。假设序列长度为n,那么这个序列的中间值可以通过(S / n)得到,知道序列的中间值和长度,也就不难求出这段序列了。

2)满足条件的n分两种情况:

     n为奇数时,序列中间的数正好是序列的平均值,所以条件为:(n & 1) == 1 && sum % n == 0;

     n为偶数时,序列中间两个数的平均值是序列的平均值,而这个平均值的小数部分为0.5,所以条件为:(sum % n) * 2 == n.

3)由题可知n >= 2,那么n的最大值是多少呢?我们完全可以将n从2到S全部遍历一次,但是大部分遍历是不必要的。为了让n尽可能大,我们让序列从1开始,

     根据等差数列的求和公式:S = (1 + n) * n / 2,得到.

     最后举一个例子,假设输入sum = 100,我们只需遍历n = 13~2的情况(按题意应从大到小遍历),n = 8时,得到序列[9, 10, 11, 12, 13, 14, 15, 16];n  = 5时,得到序列[18, 19, 20, 21, 22]。

完整代码:时间复杂度为

import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
        for (int n = (int) Math.sqrt(2 * sum); n >= 2; n--) {
            if ((n & 1) == 1 && sum % n == 0 || (sum % n) * 2 == n) {
                ArrayList<Integer> list = new ArrayList<>();
                for (int j = 0, k = (sum / n) - (n - 1) / 2; j < n; j++, k++) {
                    list.add(k);
                }
                ans.add(list);
            }
        }
        return ans;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 设有一个字符数组,现对数组中的元音字母做一个统计。 2. 设计一个Java程序,设有一个给定的int类型数组并有一批数据,现让你用二种以上的方法对其进行升或降序排列。 3. 写一个简单程序,判断输入的一串字符串是否为身份证号码,注意身份证判别的几个条件。 4. 设计一个方法接收一个int数,然后返回它的反转字符串。如n=1234,则输出:4321 5. 设计一个方法接收一个三位的整数,如果是一个水仙花数,此方法返回一个布尔true值,否则是false值。再设计一个方法遍历100至999,对每个数都借用刚才的方法判断其是否是水仙花数,如果是打印出来,否则就是下一个。所谓水仙花数,是一个3位数,其各位的立方和等该数自身。如:153=1的三次方*5的三次方*3的三次方 6. 设计一个方法,接收一个四位整数,然后此方法判断这个4位数的9倍是该4位数的反序数。如:4位数的1089的9倍是9801。9801是1089的反序数。最后把具有这种特性的4位数全都打印出来。 7. 有以下15位身份证数据,假设被存在sfzMessage中; sfzMessage=“370102770102413, 370102760807911, 370102660810114,…” 现在把这组数据变为18位,结果为 “ 37010219770102413A, 37010219760807911B, 370102196608101149” 为简单实现,最后一位可随机产生”10X23456789”中的任何一个来补充 8. 设计一个方法要求检查一个指定字符是否允许作为 Java 标识符中的首字符,并测试。 9. 设计一个类并提供一个方法,将整型值转换为二进制、十六进制和八进制值 10. 设计一个方法,接收三个参数分别是年,月,日,然后返加一个Calender类型的对象,再设计一个方法接收Calender类型对象,在方法内分别打印此日期是一个月的第几天,一年的第几天,一周的第几天,此天是周几,这个月的第一天是周几,是一周的第几天。 11. public static void main(String[] args) { String s = new String("abc");//执行到这一行时,创建了几个对象? String s1 = "abc";//执行到这一行时,创建了几个对象? String s2 = new String("abc");//执行到这一行时,创建了几个对象? System.out.println(s == s1);//输出结果是什么? System.out.println(s == s2);//输出结果是什么? System.out.println(s2 == s1);//输出结果是什么? } 12. 使用System类的getProperty()获取Java的安装目录,java的类库路径,用户当前目录、用户名、路径分隔符5个属性 13. 使用Random类nextInt()函数产生10个1-9的随机整数。ran.nextInt(9) + 1 14. 首先定义一个StringBuffer类对象S,然后通过append()方法为对象添加26个小写字母,要求每次添加一个字母,共添加26次。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值