lintcode阶梯训练第二关(九章)

一、OOXX

14、二分查找

  • 题目
    给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1。
    样例
    在数组 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2。

  • 代码

class Solution {
    public int binarySearch(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        int start = 0;
        int end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (nums[start] == target) {
            return start;
        }
        if (nums[end] == target) {
            return end;
        }
        return -1;
    }
}

457、经典二分查找问题

  • 题目
    在一个排序数组中找一个数,返回该数出现的任意位置,如果不存在,返回-1。
    样例
    给出数组 [1, 2, 2, 4, 5, 5].
    对于 target = 2, 返回 1 或者 2.
    对于 target = 5, 返回 4 或者 5.
    对于 target = 6, 返回 -1.

  • 代码

class Solution {
    public int findPosition(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        int start = 0;
        int end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (nums[start] == target) {
            return start;
        }
        if (nums[end] == target) {
            return end;
        }
        return -1;
    }
}

458、目标最后位置

  • 题目
    给一个升序数组,找到target最后一次出现的位置,如果没出现过返回-1。
    样例
    给出 [1, 2, 2, 4, 5, 5].
    target = 2, 返回 2.
    target = 5, 返回 5.
    target = 6, 返回 -1.

  • 代码

class Solution {
    public int lastPosition(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        int start = 0;
        int end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] <= target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (nums[end] == target) {
            return end;
        }
        if (nums[start] == target) {
            return start;
        }
        return -1;
    }
}

74、第一个错误的代码版本

  • 题目
    代码库的版本号是从 1 到 n 的整数。某一天,有人提交了错误版本的代码,因此造成自身及之后版本的代码在单元测试中均出错。请找出第一个错误的版本号。
    你可以通过 isBadVersion 的接口来判断版本号 version 是否在单元测试中出错,具体接口详情和调用方法请见代码的注释部分。
    注意事项
    请阅读上述代码,对于不同的语言获取正确的调用 isBadVersion 的方法,比如java的调用方式是SVNRepo.isBadVersion(v)。
    样例
    给出 n=5
    调用isBadVersion(3),得到false
    调用isBadVersion(5),得到true
    调用isBadVersion(4),得到true
    此时我们可以断定4是第一个错误的版本号

  • 代码

class Solution {
    public int findFirstBadVersion(int n) {
        int start = 1;
        int end = n;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (SVNRepo.isBadVersion(mid)) {
                end = mid;
            } else {
                start = mid;
            }
        }
        if (SVNRepo.isBadVersion(start)) {
            return start;
        } else {
            return end;
        }
    }
}

447、在大数组中查找

  • 题目
    给一个按照升序排序的正整数数组。这个数组很大以至于你只能通过固定的接口 ArrayReader.get(k) 来访问第k个数。(或者C++里是ArrayReader->get(k)),并且你也没有办法得知这个数组有多大。找到给出的整数target第一次出现的位置。你的算法需要在O(logk)的时间复杂度内完成,k为target第一次出现的位置的下标。
    如果找不到target,返回-1。
    注意事项
    如果你访问了 ArrayReader 中一个不可访问的下标(比如越界),ArrayReader 会返回 MAXINT = 2,147,483,647。
    样例
    给出 [1, 3, 6, 9, 21, …], and target = 3, return 1.
    给出 [1, 3, 6, 9, 21, …], and target = 4, return -1.

  • 代码

class Solution {
    public int searchBigSortedArray(ArrayReader reader, int target) {
        int index = 1;
        while (reader.get(index - 1) < target) {
            index *= 2;
        }
        int start = 0;
        int end = index - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (reader.get(mid) < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (reader.get(start) == target) {
            return start;
        }
        if (reader.get(end) == target) {
            return end;
        }
        return -1;
    }
}

460、排序数组中最接近元素

  • 题目
    在一个排好序的数组 A 中找到 i 使得 A[i] 最接近 target
    注意事项
    There can be duplicate elements in the array, and we can return any of the indices with same value.
    样例
    [1, 2, 3] target = 2, 返回 1.
    [1, 4, 6] target = 3, 返回 1.
    [1, 4, 6] target = 5, 返回 1 或者 2.
    [1, 3, 3, 4] target = 2, 返回 0 或者 1 或者 2.

  • 代码

public class Solution {
    public int closestNumber(int[] A, int target) {
        if (A == null || A.length == 0) {
            return -1;
        }
        int start = 0;
        int end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] == target) {
                return mid;
            }else if (A[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        return Math.abs(A[start] - target) < Math.abs(A[end] - target) ? start : end;
    }
}

159、寻找旋转排序数组中的最小值

  • 题目
    假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2)。
    你需要找到其中最小的元素。
    你可以假设数组中不存在重复的元素。
    样例
    给出[4,5,6,7,0,1,2] 返回 0

  • 代码

public class Solution {
    public int findMin(int[] nums) {
        int start = 0;
        int end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] < nums[end]) {
                end = mid;
            } else {
                start = mid;
            }
        }
        return Math.min(nums[start], nums[end]);
    }
}

160、寻找旋转排序数组中的最小值 II

  • 题目
    假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2)。
    你需要找到其中最小的元素。
    数组中可能存在重复的元素。
    样例
    给出[4,4,5,6,7,0,1,2] 返回 0

  • 代码

public class Solution {
    public int findMin(int[] nums) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            min = Math.min(nums[i], min);
        }
        return min;
    }
}

若用二分:

public class Solution {
    public int findMin(int[] nums) {
        int start = 0;
        int end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] == nums[end]) {
                end--;
            } else if (nums[mid] <= nums[end]) {
                end = mid;
            } else {
                start = mid;
            }
        }
        return Math.min(nums[start], nums[end]);
    }
}

28、搜索二维矩阵

  • 题目
    写出一个高效的算法来搜索 m × n矩阵中的值。
    这个矩阵具有以下特性:
    每行中的整数从左到右是排序的。
    每行的第一个数大于上一行的最后一个整数。
    样例
    考虑下列矩阵:
    [
    [1, 3, 5, 7],
    [10, 11, 16, 20],
    [23, 30, 34, 50]
    ]
    给出 target = 3,返回 true

  • 代码

public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0) {
            return false;
        }
        if (matrix[0] == null || matrix[0].length == 0) {
            return false;
        }
        int len = matrix.length * matrix[0].length;
        int m = matrix[0].length;
        int start = 0;
        int end = len - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (matrix[mid / m][mid % m] == target) {
                return true;
            } else if (matrix[mid / m][mid % m] > target){
                end = mid;
            } else {
                start = mid;
            }
        }
        return matrix[start / m][start % m] == target || matrix[end / m][end % m] == target;
    }
}

38、搜索二维矩阵 II

  • 题目
    写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数。
    这个矩阵具有以下特性:
    每行中的整数从左到右是排序的。
    每一列的整数从上到下是排序的。
    在每一行或每一列中没有重复的整数。
    样例
    考虑下列矩阵:
    [
    [1, 3, 5, 7],
    [2, 4, 7, 8],
    [3, 5, 9, 10]
    ]
    给出target = 3,返回 2

  • 代码

public class Solution {
    public int searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0) {
            return 0;
        }
        if (matrix[0] == null || matrix[0].length == 0) {
            return 0;
        }
        int n = matrix.length;
        int m = matrix[0].length;
        int x = n - 1;
        int y = 0;
        int count = 0;
        while (x >= 0 && y < m) {
            if (matrix[x][y] < target) {
                y++;
            } else if (matrix[x][y] > target) {
                x--;
            } else {
                y++;
                x--;
                count++;
            }
        }
        return count;
    }
}

61、搜索区间

  • 题目
    给定一个包含 n 个整数的排序数组,找出给定目标值 target 的起始和结束位置。
    如果目标值不在数组中,则返回[-1, -1]
    样例
    给出[5, 7, 7, 8, 8, 10]和目标值target=8,
    返回[3, 4]

  • 代码

public class Solution {
    public int[] searchRange(int[] A, int target) {
        int[] ans = new int[2];
        if (A == null || A.length == 0) {
            ans[0] = -1;
            ans[1] = -1;
            return ans;
        }
        int start = 0;
        int end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (A[start] == target) {
            ans[0] = start;
        } else if (A[end] == target) {
            ans[0] = end;
        } else {
            ans[0] = -1;
            ans[1] = -1;
            return ans;
        }
        start = 0;
        end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] <= target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (A[end] == target) {
            ans[1] = end;
        } else {
            ans[1] = start;
        }
        return ans;
    }
}

462、目标出现总和

  • 题目
    给一个升序的数组,以及一个target,找到它在数组中出现的次数。
    样例
    给出 [1, 3, 3, 4, 5] target = 3, 返回 2.
    给出 [2, 2, 3, 4, 6] target = 4, 返回 1.
    给出 [1, 2, 3, 4, 5] target = 6, 返回 0.

  • 代码

public class Solution {
    public int totalOccurrence(int[] A, int target) {
        if (A == null || A.length == 0) {
            return 0;
        }
        if (A[0] > target || A[A.length - 1] < target) {
            return 0;
        }
        int left;
        int start = 0;
        int end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (A[start] == target) {
            left = start;
        } else if (A[end] == target) {
            left = end;
        } else {
            return 0;
        }
        int right;
        start = 0;
        end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] <= target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (A[end] == target) {
            right = end;
        } else {
            right = start;
        }
        return right - left + 1;
    }
}

585、Maximum Number in Mountain Sequence

  • 题目
    Given a mountain sequence of n integers which increase firstly and then decrease, find the mountain top.
    样例
    Given nums = [1, 2, 4, 8, 6, 3] return 8
    Given nums = [10, 9, 8, 7], return 10

  • 代码

public class Solution {
    public int mountainSequence(int[] nums) {
        if (nums == null || nums.length == 0) {
            return -1; 
        }
        int start = 0;
        int end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] < nums[mid + 1]) {
                start = mid;
            } else {
                end = mid;
            }
        }
        return Math.max(nums[start], nums[end]);
    }
}

二、Half half

75、寻找峰值

  • 题目
    你给出一个整数数组(size为n),其具有以下特点:
    相邻位置的数字是不同的
    A[0] < A[1] 并且 A[n - 2] > A[n - 1]
    假定P是峰值的位置则满足A[P] > A[P-1]且A[P] > A[P+1],返回数组中任意一个峰值的位置。
    样例
    给出数组[1, 2, 1, 3, 4, 5, 7, 6]返回1, 即数值 2 所在位置, 或者6, 即数值 7 所在位置.
    【需要再做一遍~】

  • 代码
    (也可以用585的解法,不过这个更快)

public class Solution {
    public int findPeak(int[] A) {
        if (A == null || A.length == 0) {
            return -1;
        }
        int start = 0;
        int end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] < A[mid - 1]) {
                end = mid;
            } else if (A[mid] < A[mid + 1]) {
                start = mid;
            } else {
                return mid;
            }
        }
        return -1;
    }
}

62、搜索旋转排序数组

  • 题目
    假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2)。给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。
    你可以假设数组中不存在重复的元素。
    样例
    给出[4, 5, 1, 2, 3]和target=1,返回 2
    给出[4, 5, 1, 2, 3]和target=0,返回 -1

  • 代码

public class Solution {
    public int search(int[] A, int target) {
        if (A == null || A.length == 0) {
            return -1;
        }
        int start = 0;
        int end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] < A[end]) {
                if (A[mid] <= target && target <= A[end]) {
                    start = mid;
                } else {
                    end = mid;
                }
            } else {
                if (A[start] <= target && target <= A[mid]) {
                    end = mid;
                } else {
                    start = mid;
                }
            }
        }
        if (A[start] == target) {
            return start;
        }
        if (A[end] == target) {
            return end;
        }
        return -1;
    }
}

63、搜索旋转排序数组 II

  • 题目
    跟进“搜索旋转排序数组”,假如有重复元素又将如何?
    是否会影响运行时间复杂度?
    如何影响?
    为何会影响?【影响时间复杂度,二分法和for循环时间复杂度都是O(n)】
    写出一个函数判断给定的目标值是否出现在数组中。
    【要考虑最坏的情况例如11111……1中有个0】
    样例
    给出[3,4,4,5,7,0,1,2]和target=4,返回 true

  • 代码

public class Solution {
    public boolean search(int[] A, int target) {
        if (A == null || A.length == 0) {
            return false;
        }
        for (int i = 0; i < A.length; i++) {
            if (A[i] == target) {
                return true;
            }
        }
        return false;
    }
}

若用二分:

public class Solution {
    public boolean search(int[] A, int target) {
        if (A == null || A.length == 0) {
            return false;
        }
        int start = 0;
        int end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] == A[end]) {
                end--;
            } else if (A[mid] < A[end]) {
                if (A[mid] <= target && target <= A[end]) {
                    start = mid;
                } else {
                    end = mid;
                }
            } else {
                if (A[start] <= target && target <= A[mid]) {
                    end = mid;
                } else {
                    start = mid;
                }
            }
        }
        return A[start] == target || A[end] == target;
    }
}

三、二分答案

141、x的平方根

  • 题目
    实现 int sqrt(int x) 函数,计算并返回 x 的平方根。
    样例
    sqrt(3) = 1
    sqrt(4) = 2
    sqrt(5) = 2
    sqrt(10) = 3

  • 代码

class Solution {
    public int sqrt(int x) {
        long start = 0;
        long end = x;
        while (start + 1 < end) {
            long mid = start + (end - start) / 2;
            if (mid * mid == x) {
                return (int) mid;
            } else if (mid * mid < (long) x) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (end * end <= (long) x) {
           return (int) end;
        }
        return (int) start;
    }
}

586、Sqrt(x) II

  • 题目
    Implement double sqrt(double x) and x >= 0.
    Compute and return the square root of x.
    样例
    Given n = 2 return 1.41421356
    【需要再来遍~】

  • 代码

public class Solution {
    public double sqrt(double x) {
        double start = 0.0;
        double end = x;
        if (end < 1.0) {
            end = 1.0;
        }
        double e = 1e-12;
        while (start + e < end) {
            double mid = (start + end) / 2;
            if (mid * mid < x) {
                start = mid;
            } else {
                end = mid;
            }
        }
        return start;
    }
}

183、木材加工

  • 题目
    有一些原木,现在想把这些木头切割成一些长度相同的小段木头,需要得到的小段的数目至少为 k。当然,我们希望得到的小段越长越好,你需要计算能够得到的小段木头的最大长度。
    注意事项
    木头长度的单位是厘米。原木的长度都是正整数,我们要求切割得到的小段木头的长度也要求是整数。无法切出要求至少 k 段的,则返回 0 即可。
    样例
    有3根木头[232, 124, 456], k=7, 最大长度为114.

  • 代码

public class Solution {
    public int woodCut(int[] L, int k) {
        if (L == null || L.length == 0) {
            return 0;
        }
        int start = 1;
        int max = 0;
        for (int i = 0; i < L.length; i++) {
            if (L[i] > max) {
                max = L[i];
            }
        }
        int end = max;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (getK(mid, L) >= k) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (getK(end, L) >= k) {
            return end;
        }
        if (getK(start, L) >= k) {
            return start;
        }
        return 0;
    }
    private int getK(int x, int[] L) {
        int count = 0;
        for (int i = 0; i < L.length; i++) {
            count += L[i] / x;
        }
        return count;
    }
}

437、书籍复印

  • 题目
    给出一个数组A包含n个元素,表示n本书以及各自的页数。现在有个k个人复印书籍,每个人只能复印连续一段编号的书,比如A[1],A[2]由第一个人复印,但是不能A[1],A[3]由第一个人复印,求最少需要的时间复印所有书。
    样例
    A = [3,2,4],k = 2
    返回5,第一个人复印前两本书
    【需要再来一遍~】

  • 代码

public class Solution {
    public int copyBooks(int[] pages, int k) {
        if (pages == null || pages.length == 0) {
            return 0;
        }
        int sum = 0;
        int max = 0;
        for (int i = 0; i < pages.length; i++) {
            sum += pages[i];
            if (pages[i] > max) {
                max = pages[i];
            }
        }
        int start = max;
        int end = sum;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (getK(mid, pages) > k) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (getK(start, pages) <= k) {
            return start;
        }
        if (getK(end, pages) <= k) {
            return end;
        }
        return 0;
    }
    private int getK(int x, int[] pages) {
        int sum = 0;
        int ans = 1;
        for (int i = 0; i < pages.length; i++) {
            if (sum + pages[i] > x) {
                ans++;
                sum = 0;
            }
            sum += pages[i];
        }
        return ans;
    }
}

四、练习

414、两个整数相除

  • 题目
    将两个整数相除,要求不使用乘法、除法和 mod 运算符。
    如果溢出,返回 2147483647 。
    【需要再来一遍~】
    样例
    给定被除数 = 100 ,除数 = 9,返回 11。

  • 代码

public class Solution {
    public int divide(int dividend, int divisor) {
        if (divisor == 0) {
            return Integer.MAX_VALUE;
        }
        if (dividend == 0) {
            return 0;
        }
        if (dividend == Integer.MIN_VALUE && divisor == -1) {
            return Integer.MAX_VALUE;
        } //为什么要有这步,因为MIN_VALUE取绝对值会溢出
        long a = Math.abs((long) dividend);
        long b = Math.abs((long) divisor);
        boolean isNegative = (dividend > 0 && divisor < 0) ||
                             (dividend < 0 && divisor > 0);
        int result = 0;
        while (a >= b) {
            int shift = 0;
            while (a >= (b << shift)) {
                shift++;
            }
            a -= b << (shift - 1);
            result += 1 << (shift - 1);
        }
        return isNegative ? -result : result;
    }
}

460、在排序数组中找最接近的K个数

  • 题目
    给一个目标数 target, 一个非负整数 k, 一个按照升序排列的数组 A。在A中找与target最接近的k个整数。返回这k个数并按照与target的接近程度从小到大排序,如果接近程度相当,那么小的数排在前面。
    【需要再来一遍~】
    样例
    如果 A = [1, 2, 3], target = 2 and k = 3, 那么返回 [2, 1, 3].
    如果 A = [1, 4, 6, 8], target = 3 and k = 3, 那么返回 [4, 1, 6].

  • 代码

public class Solution {
    public int[] kClosestNumbers(int[] A, int target, int k) {
        if (A == null || A.length == 0) {
            return A;
        }
        int[] result = new int[k];
        int index = firstIndex(A, target);
        int start = index - 1;
        int end = index;
        for (int i = 0; i < k; i++) {
            if (start < 0) {
                result[i] = A[end++];
            } else if (end >= A.length) {
                result[i] = A[start--];
            } else {
                if (target - A[start] <= A[end] - target) {
                    result[i] = A[start--];
                } else {
                    result[i] = A[end++];
                }
            }
        }
        return result;
    }
    private int firstIndex(int[] A, int target) {
        int start = 0;
        int end = A.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (A[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (A[start] >= target) {
            return start;
        }
        if (A[end] >= target) {
            return end;
        }
        return A.length;
    }
}

600、Smallest Rectangle Enclosing Black Pixels

  • 题目
    An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black pixels are connected, i.e., there is only one black region. Pixels are connected horizontally and vertically. Given the location (x, y) of one of the black pixels, return the area of the smallest (axis-aligned) rectangle that encloses all black pixels.
    样例
    For example, given the following image:
    [
    “0010”,
    “0110”,
    “0100”
    ]
    and x = 0, y = 2,
    Return 6.

  • 代码

public class Solution {
    public int minArea(char[][] image, int x, int y) {
        if (image == null || image.length == 0) {
            return 0;
        }
        if (image[0] == null || image[0].length == 0) {
            return 0;
        }
        int n = image.length;
        int m = image[0].length;
        int left = 0;
        int start = 0;
        int end = y;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (colHas(image, mid)) {
                end = mid;
            } else {
                start = mid;
            }
        }
        if (colHas(image, start)) {
            left = start;
        } else if (colHas(image, end)) {
            left = end;
        } else {
            return 0;
        }
        int right = 0;
        start = y;
        end = m - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (colHas(image, mid)) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (colHas(image, end)) {
            right = end;
        } else if (colHas(image, start)) {
            right = start;
        }
        int up = 0;
        start = 0;
        end = x;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (rowHas(image, mid)) {
                end = mid;
            } else {
                start = mid;
            }
        }
        if (rowHas(image, start)) {
            up = start;
        } else if (rowHas(image, end)) {
            up = end;
        }
        int down = 0;
        start = x;
        end = n - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (rowHas(image, mid)) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (rowHas(image, end)) {
            down = end;
        } else if (rowHas(image, start)) {
            down = start;
        }
        return (right - left + 1) * (down - up + 1);
    }
    private boolean colHas(char[][] image, int y) {
        for (int i = 0; i < image.length; i++) {
            if (image[i][y] == '1') {
                return true;
            }
        }
        return false;
    }
    private boolean rowHas(char[][] image, int x) {
        for (int i = 0; i < image[0].length; i++) {
            if (image[x][i] == '1') {
                return true;
            }
        }
        return false;
    }
}

617、Maximum Average Subarray

  • 题目
    Given an array with positive and negative numbers, find the maximum average subarray which length should be greater or equal to given length k.
    【需要再来一遍~】
    注意事项
    It’s guaranteed that the size of the array is greater or equal to k.
    样例
    Given nums = [1, 12, -5, -6, 50, 3], k = 3
    Return 15.667 // (-6 + 50 + 3) / 3 = 15.667

  • 代码

public class Solution {
    public double maxAverage(int[] nums, int k) {
        if (nums == null || nums.length < k) {
            return 0;
        }
        double r = Integer.MIN_VALUE;
        double l = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] < l) {
                l = nums[i];
            }
            if (nums[i] > r) {
                r = nums[i];
            }
        }
        double[] sums = new double[nums.length + 1];
        sums[0] = 0;
        while (r - l >= 1e-6) {
            double mid = (r + l) / 2.0;
            double min_pre = 0;
            boolean check = false;
            for (int i = 1; i <= nums.length; i++) {
                sums[i] = sums[i - 1] + nums[i - 1] - mid;
                if (i >= k && sums[i] - min_pre >= 0) {
                    check = true;
                    break;
                } else if (i >= k) {
                    min_pre = Math.min(min_pre, sums[i - k + 1]);
                }
            }
            if (check) {
                l = mid;
            } else {
                r = mid;
            }
        }
        return l;
    }
}

254、Drop Eggs

  • 题目
    There is a building of n floors. If an egg drops from the k th floor or above, it will break. If it’s dropped from any floor below, it will not break.
    You’re given two eggs, Find k while minimize the number of drops for the worst case. Return the number of drops in the worst case.
    说明
    For n = 10, a naive way to find k is drop egg from 1st floor, 2nd floor … kth floor. But in this worst case (k = 10), you have to drop 10 times.
    Notice that you have two eggs, so you can drop at 4th, 7th & 9th floor, in the worst case (for example, k = 9) you have to drop 4 times.
    样例
    Given n = 10, return 4.
    Given n = 100, return 14.
    【题目没懂】

你可能感兴趣的:(leetcode,lintcode)