题解 | #合唱队#

合唱队

https://www.nowcoder.com/practice/6d9d69e3898f45169a441632b325c7b4

import java.util.Scanner;

// 问题可以转换成最长递增/递减子序列问题, 二分查找使查找的时间效率从O(N)
// 降为O(logN) 
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int N = in.nextInt();
            int[] heights = new int[N];
            for (int i = 0; i < N; i++) {
                heights[i] = in.nextInt();
            }
            System.out.println(pick(heights));
        }
    }

    public static int pick(int[] h) {
        int n = h.length, out = n;
        for (int i = 0; i < n; i++) {
            int l_len = count(h, 0, i, true);
            int r_len = count(h, i, n - 1, false);
            out = Math.min(out, n - (l_len + r_len - 1));
        }
        return out;
    }

    //获取某个人左边的最长递增身高序列,或右边的最长递减身高序列
    //这里用 二分提高查找效率
    public static int count(int[] h, int left, int right, boolean isUp) {
        int res = 0;
        int[] tail = new int[right - left + 1];
        for (int i = left; i <= right; i++) {
            int l = 0, r = res;
            while (l < r) {
                int mid = (r + l) / 2;
                if (isUp) {
                    if (tail[mid] < h[i]) {
                        l = mid + 1;
                    } else {
                        r = mid;
                    }
                } else {
                    if (tail[mid] > h[i]) {
                        l = mid + 1;
                    } else {
                        r = mid;
                    }
                }
            }
            if (l == res) {
                res++;
            }
            tail[l] = h[i];
        }
        return res;
    }
}

全部评论

相关推荐

02-17 20:43
西北大学 Java
醉蟀:别浪费时间。老板是一个想入行互联网的新人。去年6 7月boss上面看到的。他把所有人都拉到一个微信群,然后一个一个面,自己也在学技术。公司就是一个小区里面租的两间房。都没有买电脑啥的。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务