《剑指Offer》— Java版(Problem 61 - 68)

Problem 61:扑克牌的顺子

    public boolean isContinuous(int [] arr) {
        if(arr == null || arr.length < 5) return false;
        int zeroCount = 0;
        Arrays.sort(arr);
        for(int num : arr)
            if(num == 0)
                zeroCount++;
        for(int i = zeroCount; i < arr.length - 1; i++){
            if(arr[i] == arr[i+1]) return false;
            zeroCount -= arr[i+1] - arr[i] - 1;
        }
        return zeroCount >= 0;
    }

Problem 62:圆圈中最后剩下的数字(约瑟夫环问题)

    public int LastRemaining_Solution(int n, int m) {
        if(n == 0) return -1;
        if(n == 1) return 0;
        return (LastRemaining_Solution(n-1, m) + m) % n;
    }

Problem 63:股票最大的收益

public int maxProfit(int[] prices){
	if(prices == null || prices.length) return 0;
	int soFarMin = prices[0]; // 当前买入的最低价格
	int maxProfit = 0;
	for(int i = 1; i < prices.length; i++){
		soFarMin = Math.min(soFarMin, pirces[i]);
		maxProfit = Math.max(maxProfit, maxProfit - soFarMin);
	}
	return maxProfit;
}

Problem 64:求1+2+……+n

public int Sum(int n){
	int sum = m;
	boolean a = (n > 0) && ((sum += Sum(n - 1)) > 0);
	return sum;
}

Problem 65:不用 + - * / 实现加法运算

public int Add(int num1, int num2){
	return (num2 == 0) ? num1 : Add(num1 ^ num2, (num1 & num2) << 1);
}

Problem 66:构建乘积数组

    public int[] multiply(int[] A) {
        int[] B = new int[A.length];
        for(int i = 0, product = 1; i < A.length; product *= A[i], i++)
            B[i] = product;
        for(int i = A.length - 1, product = 1; i >= 0; product *= A[i], i--)
            B[i] *= product;
        return B;
    }

Problem 67:将字符串转为一个整数

public int StrToInt(String str){
	if(str == null || str.length == 0) return 0;
	char[] chars = str.toCharArray();
	boolean isNegative = (str.charAt(0) == '-');
	int result = 0;
	for(int i = 0; i < str.length(); i++){
		char c = str.charAt(i);
		if(i = 0 && (c == '-' || c == '+'))
			continue;
		if(c < '0' || c > '9')
			return 0;
		result += result * 10 + (c - '0');
	}
	return isNegative ? -result : result;
}

Problem 68:求两个节点的最近公共祖先

如果树是一棵二叉搜索树,则如果当前节点值小于两个节点,则两个节点处于当前节点的右子树中,反之处于左子树中
public TreeNode findLowestAncestor(TreeNode root, TreeNode p, TreeNode q){
	if(root == null || root == p || root == q) return root;
	if(root.val < p.val && root.val < q.val)
		return findLowestAncestor(root.right, p, q);
	if(root.val > p.val && root.val > q.val)
		return findLowestAncestor(root.left, p, q);
	return root;
}
如果树是一棵普通树,但是每个节点都有指向父节点的指针,则变为以两个节点为头节点的链表,求最近公共节点的问题
public TreeNode findLowestAncestor(TreeNode p, TreeNode q){
	while(p != q){
		p = (p == null) ? q : p.next;
		q = (q == null) ? p : q.next;
	}
	return p;
}
如果树是一个普通树,且没有指向父节点的指针,则从上往下遍历,看有没有一棵子树包含这两个节点,如果有,得到包含两个节点的最深子树的树根,没有返回null
public TreeNode findLowestAncestor(TreeNode root, TreeNode p, TreeNode q){
	if(root == null || root == p || root == q) return root;
	//一值往下搜索,直到最深子树
	TreeNode left = findLowestAncestor(root.left, p, q);
	TreeNode right = findLowestAncestor(root.right, p, q);
	//看看树的左边还含不含其中一个节点,含的话再去右边看看,如果右边含有另一个节点,
	//则当前根节点就是最近公共祖先了
	return left == null ? right : (right == null ? left : root);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值