leetcode 解题记录

leetcode 解题记录

11. Container With Most Water

题目描述
Given n non-negative integers a1, a2, …, an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.
图片实例

图片示例

The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
Example:

Input: [1,8,6,2,5,4,8,3,7]
Output: 49

我的解法(解法1):我的解法(解法1):

public class Solution{
    public int maxArea(int[] height){
        int length = height.length;
        int volumn  = 0;
        for (int i=0;i<length-1;i++){
            for(int j=i+1;j<=length-1;j++){
                int current_vol = (j-i)*Math.min(height[i],height[j]);
                if(volumn<current_vol)
                    volumn = current_vol;
            }
        }
        return volumn;
    }
}

更好的解法(解法2)

class Solution {
    public int maxArea(int[] height) {
        int max = 0, vol=0;
        int i=0;
        int j = height.length-1;
        while(i!=j){
            vol = Math.min(height[i], height[j]) * (j-i);
            max = (vol > max) ? vol : max;
            if(height[i]>height[j]) j--;
            else i++;
        }
        return max;
    }
}

评论:
单纯的遍历复杂度为O(n^2)
解法2复杂度为O(n),进步的不是一点点。
既然循环次数少了这么多。那么有没有解法1中碰到的情况解法2中没有考虑呢?其实是有的,但是对于2来说,已经将肯定不是最大的情况直接排除了。

29. Divide Two Integers

题目描述:
Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.

Return the quotient after dividing dividend by divisor.

The integer division should truncate toward zero.

Example 1:

Input: dividend = 10, divisor = 3
Output: 3

Example 2:

Input: dividend = 7, divisor = -3
Output: -2

Note:

Both dividend and divisor will be 32-bit signed integers.
The divisor will never be 0.
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.

神仙操作的解法:

public class Solution {
    public int divide(int dividend, int divisor) {
		if(dividend==Integer.MIN_VALUE && divisor==-1) return Integer.MAX_VALUE;
        if(dividend > 0 && divisor > 0) return divideHelper(-dividend, -divisor);
        else if(dividend > 0) return -divideHelper(-dividend,divisor);
        else if(divisor > 0) return -divideHelper(dividend,-divisor);
        else return divideHelper(dividend, divisor);
    }
    
    private int divideHelper(int dividend, int divisor){
        // base case
        if(divisor < dividend) return 0;
        // get highest digit of divisor
        int cur = 0, res = 0;
        while((divisor << cur) >= dividend && divisor << cur < 0 && cur < 31) cur++;
        res = dividend - (divisor << cur-1);
        if(res > divisor) return 1 << cur-1;
        return (1 << cur-1)+divide(res, divisor);
    }
}

评论
想要明白本解法,需要有的知识有:

  • java中的byte数据类型

  • java中的按位左移、右移操作

  • CPU中只有加法器,怎么通过加法实现乘除法运算 补码反码

  • 首先byte是一个字节,有八位,表示范围是-127~+128
    在java中int是32位,double是64位

  • 其次,按位移动操作:
    按位操作是操作于byte数据上,如果操作数不是byte类型需要转换成byte型,这里涉及到int–>byte等知识点
    一个重要的知识点是:
    一个二进制左移一位相当于乘2, 如二进制1左移一位:
    0001>>1 = 0010 变为2

    右移一位相当于处以2

这个解法先将除数、被除数都转化为负数便于位操作的一致性
采用了用了递归的方法
举个例子说,以123为dividend, 3为divisor 调用过程如下
divide(123, 3)
变为负数:
divideHelpler(-123, -3)
cur 从0开始自增 来执行 -3 <<cur, 我们知道<<相当于除以2, 于是-32, -32*2 …
循环保持的条件是

  • (divisor << cur) >= dividend: 此时除数乘出来的结果的绝对值比比被除数小,表示还可以再乘以2
  • divisor << cur < 0: 此时除数被一直乘2但还是与之前符号一致是负数,因此除数还没有溢出
  • cur < 31: 因为规定了被除数是int类型最多只有32位,所以只能左移31位最多
    因此对于divideHelpler(-123, -3)来说,
    -3最多乘以6个2得到-192开始小于-123, 此时结束循环,cursor等于6
    res = -123 - (-325) = -27
    然后因为-27 < -3不满足if于是返回值为
    (1<<cur-1)+ divide(res,divisor)
    (1<<cur-1) = 1
    25=32
    再用res重新跑上面函数,得到
    -27 = -3*23-3
    此时res = -3, cur-1=3
    于是32+3 = 35 余下res=-3
    再调用divideHelpler(-3, -3)得到cur-1 = 1
    res = 0 > divisor = -3
    结束循环
    最后的结果是
    32+3+1 = 36
    结果是每次调用的cur-1加到一起去
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值