[左神面试指南] 数组和矩阵[下]篇

CD26 子数组的最大累加和问题

public class CD26_1
{
    public static int solution(int[] arr)
    {
        int ans = -1, sum = 0;
        for (int num : arr)
        {
            if (sum + num > 0)
            {
                sum += num;
                ans = Math.max(ans, sum);
            }
            else
                sum = 0;
        }
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n;
        n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr));
    }
}

CD27 子矩阵的最大累加和问题

public class CD27_1
{
    public static int solution(int[][] arr)
    {
        int[] temp;
        int sum = 0, ans = -1;
        for (int i = 0; i < arr.length; i++)
        {
            temp = new int[arr[0].length];
            for (int j = i; j < arr.length; j++)
            {
                sum = 0;
                for (int k = 0; k < arr[0].length; k++)
                {
                    temp[k] += arr[j][k];
                    if (sum + temp[k] > 0)
                    {
                        sum += temp[k];
                        ans = Math.max(ans, sum);
                    }
                    else sum = 0;
                }
            }
        }

        return ans;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n, m;
        n = in.nextInt();
        m = in.nextInt();
        int[][] arr = new int[n][m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                arr[i][j] = in.nextInt();
        System.out.println(solution(arr));
    }
}

CD28 在数组中找到一个局部最小的位置⭐

/* ⭐二分查找并不是数组有序时才能使用⭐ */
public class CD28_1
{
    public static int solution(int[] arr)
    {
        if (arr == null || arr.length == 0) return -1;
        if (arr.length == 1 || arr[0] < arr[1]) return 0;
        if (arr[arr.length - 1] < arr[arr.length - 2]) return arr.length - 1;
        int l = 1, r = arr.length - 2, mid;
        while (l <= r)
        {
            mid = (l + r) / 2;
            if (arr[mid] > arr[mid - 1]) r = mid - 1;
            else if (arr[mid] > arr[mid + 1]) l = mid + 1;
            else return mid;
        }
        return -1;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n;
        n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr));
    }
}

CD32 数组中子数组的最大累乘积⭐

/*⭐*/
public class CD32_1
{
    public static String solution(double[] arr)
    {
        double mmax = arr[0], mmin = arr[0], ans = arr[0];
        for (int i = 1; i < arr.length; i++)
        {
            double temp1 = mmax * arr[i], temp2 = mmin * arr[i];
            mmax = Math.max(Math.max(temp1, temp2), arr[i]);
            mmin = Math.min(Math.min(temp1, temp2), arr[i]);
            ans = Math.max(ans, mmax);
        }
        return String.format("%.2f", ans);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n;
        n = in.nextInt();
        double[] arr = new double[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextDouble();
        System.out.println(solution(arr));
    }
}

CD34 打印 N 个数组整体最大的 Top K

/* 模拟堆 */
public class CD34_1
{
    public static class Node
    {
        public int val;
        public int idx;
        public int th;

        public Node()
        {
        }

        public Node(int val, int idx, int th)
        {
            this.val = val;
            this.idx = idx;
            this.th = th;
        }
    }

    public static int[] solution(ArrayList<Integer>[] arr, int k)
    {
        int[] ans = new int[k];
        Node[] h = new Node[arr.length];
        int size = -1, index = 0;
        for (int i = 0; i < arr.length; i++)
            if (arr[i].size() != 0)
                h[++size] = new Node(arr[i].get(arr[i].size() - 1), arr[i].size() - 1, i);
        createHeap(h, size);
        while (index < k)
        {
            Node maxNode = h[0];
            ans[index++] = maxNode.val;
            if (maxNode.idx != 0)
            {
                h[0] = new Node(arr[maxNode.th].get(maxNode.idx - 1), maxNode.idx - 1, maxNode.th);
                adjustHeap(h, 0, size);
            }
            else
            {
                h[0] = h[size];
                adjustHeap(h, 0, --size);
            }
        }
        return ans;
    }

    public static void createHeap(Node[] arr, int len)
    {
        for (int i = (len - 1) / 2; i >= 0; i--)
            adjustHeap(arr, i, len);
    }

    public static void adjustHeap(Node[] arr, int idx, int len)
    {
        int cur;
        while (2 * idx + 1 <= len)
        {
            cur = 2 * idx + 1;
            if (2 * idx + 2 <= len && arr[2 * idx + 1].val < arr[2 * idx + 2].val)
                cur++;
            if (arr[idx].val < arr[cur].val)
            {
                Node temp = arr[idx];
                arr[idx] = arr[cur];
                arr[cur] = temp;
            }
            else break;
            idx = cur;
        }
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, k, n;
        N = in.nextInt();
        k = in.nextInt();
        ArrayList<Integer>[] arr = new ArrayList[N];
        Arrays.setAll(arr, e -> new ArrayList<Integer>());
        for (int i = 0; i < N; i++)
        {
            n = in.nextInt();
            while (n-- > 0)
                arr[i].add(in.nextInt());
        }
        int[] res = solution(arr, k);
        System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
    }
}

CD41 边界都是 1 的最大正方形大小

/* 模拟 */
public class CD41_1
{
    public static int solution(int[][] arr)
    {
        int len = arr.length, ans = -1;
        int[][] row = new int[len][len];
        int[][] col = new int[len][len];
        for (int i = 0; i < len; i++)
            for (int j = 0; j < len; j++)
                if (j == 0) row[i][j] = arr[i][j];
                else row[i][j] = row[i][j - 1] + arr[i][j];
        for (int j = 0; j < len; j++)
            for (int i = 0; i < len; i++)
                if (i == 0) col[i][j] = arr[i][j];
                else col[i][j] = col[i - 1][j] + arr[i][j];
        for (int i = 0; i < len; i++)
            for (int j = 0; j < len; j++)
                for (int l = Math.min(len - i, len - j); l >= 2; l--)
                    if (row[i][j + l - 1] - row[i][j] == l - 1 && col[i + l - 1][j] - col[i][j] == l - 1
                            && row[i + l - 1][j + l - 1] - row[i + l - 1][j] == l - 1 && col[i + l - 1][j + l - 1] - col[i][j + l - 1] == l - 1)
                        ans = Math.max(ans, l);
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n;
        n = in.nextInt();
        int[][] arr = new int[n][n];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                arr[i][j] = in.nextInt();
        System.out.println(solution(arr));
    }
}

CD35 不包含本位置值的累乘数组

public class CD35_1
{
    public static long[] solution(int[] arr, int p)
    {
        long[] suffix = new long[arr.length + 1];
        long[] ans = new long[arr.length];
        long prefix = 1;
        suffix[arr.length] = 1;
        for (int i = arr.length - 1; i >= 0; i--)
            suffix[i] = (suffix[i + 1] * (arr[i] % p)) % p;
        for (int i = 0; i < arr.length; i++)
        {
            ans[i] = (prefix * suffix[i + 1]) % p;
            prefix = (prefix * (arr[i] % p)) % p;
        }
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n, p;
        n = in.nextInt();
        p = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        long[] res = solution(arr, p);
        System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
    }

}

CD36 数组的 partition 调整

public class CD36_1
{
    public static int[] solution(int[] arr)
    {
        int idx = -1;
        for (int i = 0; i < arr.length; i++)
        {
            if (idx == -1 || arr[i] != arr[idx])
            {
                idx++;
                int temp = arr[i];
                arr[i] = arr[idx];
                arr[idx] = temp;
            }
        }
        return arr;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        int[] res = solution(arr);
        System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
    }
}

CD37 数组的 partition 调整(补充)

public class CD37_1
{
    public static int[] solution(int[] arr)
    {
        int index = 0, small = -1, big = arr.length;
        while (index < big)
        {
            if (arr[index] == 0) swap(arr, ++small, index++);
            else if (arr[index] == 2) swap(arr, --big, index);
            else index++;
        }
        return arr;
    }

    public static void swap(int[] arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        int[] res = solution(arr);
        System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
    }
}

CD38 求最短通路值

public class CD38_1
{
    public static int solution(String[] arr)
    {
        int n = arr.length - 1, m = arr[0].length() - 1;
        boolean[][] vis = new boolean[n + 1][m + 1];
        int[][] oris = new int[][]{{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
        Queue<int[]> que = new LinkedList<>();
        que.add(new int[]{0, 0, 1});
        while (!que.isEmpty())
        {
            int[] pollNode = que.poll();
            if (pollNode[0] == n && pollNode[1] == m) return pollNode[2];
            for (int[] ori : oris)
            {
                int nextX = pollNode[0] + ori[0], nextY = pollNode[1] + ori[1];
                if (nextX < 0 || nextX > n || nextY < 0 || nextY > m || vis[nextX][nextY] || '0' == arr[nextX].charAt(nextY))
                    continue;
                que.add(new int[]{nextX, nextY, pollNode[2] + 1});
                vis[nextX][nextY] = true;
            }
        }
        return -1;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n, m;
        n = in.nextInt();
        m = in.nextInt();
        in.nextLine();
        String[] arr = new String[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextLine();
        System.out.println(solution(arr));
    }
}

CD39 数组中未出现的最小正整数⭐

/*⭐*/
public class CD39_1
{
    public static int solution(int[] arr)
    {
        int l = 0, r = arr.length;
        while (l < r)
        {
            if (arr[l] == l + 1)
                l++;
            else if (arr[l] <= l || arr[l] > r || arr[l] == arr[arr[l] - 1])
                arr[l] = arr[--r];
            else
                swap(arr, l, arr[l] - 1);
        }
        return l + 1;
    }

    public static void swap(int[] arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        in.nextLine();
        String[] s = in.nextLine().split(" ");
        int[] arr = Arrays.stream(s).mapToInt(Integer::parseInt).toArray();
        System.out.println(solution(arr));
    }
}

CD40 数组排序之后相邻数的最大差值

/* 桶排序 */
public class CD40_1
{
    public static int solution(int[] nums)
    {
        if (nums == null || nums.length < 2) return 0;
        int len = nums.length;
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < len; i++)
        {
            min = Math.min(min, nums[i]);
            max = Math.max(max, nums[i]);
        }
        if (min == max) return 0;
        boolean[] hasNum = new boolean[len + 1];
        int[] maxs = new int[len + 1];
        int[] mins = new int[len + 1];
        int bid = 0;
        for (int i = 0; i < len; i++)
        {
            bid = bucket(nums[i], len, min, max);
            mins[bid] = hasNum[bid] ? Math.min(mins[bid], nums[i]) : nums[i];
            maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], nums[i]) : nums[i];
            hasNum[bid] = true;
        }
        int res = 0;
        int lastMax = maxs[0];
        int i = 1;
        for (; i <= len; i++)
        {
            if (hasNum[i])
            {
                res = Math.max(res, mins[i] - lastMax);
                lastMax = maxs[i];
            }
        }
        return res;
    }

    public static int bucket(long num, long len, long min, long max)
    {
        return (int) ((num - min) * len / (max - min));
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr));
    }
}

CD50 做项目的最大收益问题⭐

/*⭐模拟⭐*/
public class CD50_1
{
    public static long solution(int w, int k, int[] costs, int[] profits)
    {
        PriorityQueue<int[]> costMin = new PriorityQueue<>((o1, o2) -> o1[0] - o2[0]);
        PriorityQueue<int[]> profitMax = new PriorityQueue<>((o1, o2) -> o2[1] - o1[1]);
        long ans = w;
        for (int i = 0; i < costs.length; i++)
            costMin.add(new int[]{costs[i], profits[i]});
        while (k-- > 0)
        {
            while (!costMin.isEmpty() && ans >= costMin.peek()[0])
                profitMax.add(costMin.poll());
            if (!profitMax.isEmpty())
                ans += profitMax.poll()[1];
        }
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n, w, k;
        n = in.nextInt();
        w = in.nextInt();
        k = in.nextInt();
        int[] costs = new int[n];
        int[] profits = new int[n];
        for (int i = 0; i < n; i++)
            costs[i] = in.nextInt();
        for (int i = 0; i < n; i++)
            profits[i] = in.nextInt();
        System.out.println(solution(w, k, costs, profits));
    }
}

CD51 分金条的最小花费

public class CD51_1
{
    public static long solution(int[] arr)
    {
        PriorityQueue<Long> que = new PriorityQueue<>();
        long ans = 0;
        for (int num : arr)
            que.add((long) num);
        while (que.size() != 1)
        {
            long t = que.poll() + que.poll();
            ans += t;
            que.add(t);
        }
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n;
        n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr));
    }
}

CD52 大楼轮廓问题⭐

/*⭐*/
public class CD52_1
{
    public static class Node implements Comparable<Node>
    {
        public int x;
        public int h;
        public boolean isAdd;

        public Node(int x, boolean isAdd, int h)
        {
            this.x = x;
            this.isAdd = isAdd;
            this.h = h;
        }

        @Override
        public int compareTo(Node o)
        {
            if (this.x != o.x)
                return this.x - o.x;
            if (this.isAdd != o.isAdd)
                return this.isAdd ? -1 : 1;
            return 0;
        }
    }

    public static void solution(int[][] arr)
    {
        Node[] arrNode = new Node[arr.length * 2];
        for (int i = 0; i < arr.length; i++)
        {
            arrNode[i * 2] = new Node(arr[i][0], true, arr[i][2]);
            arrNode[i * 2 + 1] = new Node(arr[i][1], false, arr[i][2]);
        }
        Arrays.sort(arrNode);
        TreeMap<Integer, Integer> heightMap = new TreeMap<>();
        TreeMap<Integer, Integer> xMap = new TreeMap<>();
        for (Node node : arrNode)
        {
            if (node.isAdd)
                heightMap.put(node.h, heightMap.getOrDefault(node.h, 0) + 1);
            else
            {
                if (heightMap.get(node.h) == 1)
                    heightMap.remove(node.h);
                else
                    heightMap.put(node.h, heightMap.get(node.h) - 1);
            }
            if (heightMap.isEmpty())
                xMap.put(node.x, 0);
            else
                xMap.put(node.x, heightMap.lastKey());
        }

        int s = -1, h = 0;
        Set<Integer> key = xMap.keySet();
        for (int x : key)
        {
            int t = xMap.get(x);
            if (h != t)
            {
                if (h != 0)
                    System.out.println(s + " " + x + " " + h);
                s = x;
                h = t;
            }
        }
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[][] arr = new int[n][3];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < 3; j++)
                arr[i][j] = in.nextInt();
        solution(arr);
    }

}

CD53 加油站良好出发点问题❗

/*❗*/
public class CD53_1
{
    public static boolean[] solution(int[] dis, int[] oil)
    {
        if (dis == null || oil == null || dis.length < 2 || dis.length != oil.length) return null;
        int init = changeDisArrayGetInit(dis, oil);
        return init == -1 ? new boolean[dis.length] : enlargeArea(dis, init);
    }

    public static int changeDisArrayGetInit(int[] dis, int[] oil)
    {
        int init = -1;
        for (int i = 0; i < dis.length; i++)
        {
            dis[i] = oil[i] - dis[i];
            if (dis[i] >= 0)
                init = i;
        }
        return init;
    }

    public static boolean[] enlargeArea(int[] dis, int init)
    {
        boolean[] res = new boolean[dis.length];
        int start = init;
        int end = nextIndex(init, dis.length);
        long need = 0;
        long rest = 0;
        do
        {
            if (start != init && start == lastIndex(end, dis.length)) break;
            if (dis[start] < need) need -= dis[start];
            else
            {
                rest += dis[start] - need;
                need = 0;
                while (rest >= 0 && end != start)
                {
                    rest += dis[end];
                    end = nextIndex(end, dis.length);
                }

                if (rest >= 0)
                {
                    res[start] = true;
                    connectGood(dis, lastIndex(start, dis.length), init, res);
                    break;
                }
            }
            start = lastIndex(start, dis.length);
        }
        while (start != init);
        return res;
    }

    public static void connectGood(int[] dis, int start, int init, boolean[] res)
    {
        long need = 0;
        while (start != init)
        {
            if (dis[start] < need)
                need -= dis[start];
            else
            {
                res[start] = true;
                need = 0;
            }
            start = lastIndex(start, dis.length);
        }
    }

    public static int lastIndex(int index, int size)
    {
        return index == 0 ? (size - 1) : index - 1;
    }

    public static int nextIndex(int index, int size)
    {
        return index == size - 1 ? 0 : (index + 1);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] oils = new int[n];
        int[] diss = new int[n];
        for (int i = 0; i < n; i++)
            oils[i] = in.nextInt();
        for (int i = 0; i < n; i++)
            diss[i] = in.nextInt();
        boolean[] res = solution(diss, oils);
        for (boolean f : res)
            if (f) System.out.print("1 ");
            else System.out.print("0 ");
    }
}

CD54 容器盛水问题⭐

/*⭐*/
public class CD54_1
{
    public static long solution(int[] arr)
    {
        if (arr == null || arr.length < 3) return 0;
        int[] leftMaxs = new int[arr.length];
        leftMaxs[0] = arr[0];
        for (int i = 1; i < arr.length; i++)
            leftMaxs[i] = Math.max(leftMaxs[i - 1], arr[i]);
        int[] rightMaxs = new int[arr.length];
        rightMaxs[arr.length - 1] = arr[arr.length - 1];
        for (int i = arr.length - 2; i >= 0; i--)
            rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
        long res = 0;
        for (int i = 1; i < arr.length - 1; i++)
            res += Math.max(Math.min(leftMaxs[i - 1], rightMaxs[i + 1]) - arr[i], 0);
        return res;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr));
    }
}

/*单调栈*/
public class CD54_2
{
    public static long solution(int[] arr)
    {
        Stack<Integer> stack = new Stack<>();
        long ans = 0;
        for (int i = 0; i < arr.length; i++)
        {
            while (!stack.isEmpty() && arr[i] > arr[stack.peek()])
            {
                int top = stack.pop();
                if (stack.isEmpty()) break;
                int left = stack.peek();
                ans += (i - left - 1L) * (Math.min(arr[left], arr[i]) - arr[top]);
            }
            stack.add(i);
        }
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr));
    }
}

public class CD54_3
{
    public static long solution(int[] arr)
    {
        if (arr == null || arr.length < 3) return 0;
        long res = 0;
        int leftMax = arr[0];
        int rightMax = arr[arr.length - 1];
        int L = 1;
        int R = arr.length - 2;
        while (L <= R)
        {
            if (leftMax <= rightMax)
            {
                res += Math.max(0, leftMax - arr[L]);
                leftMax = Math.max(leftMax, arr[L++]);
            }
            else
            {
                res += Math.max(0, rightMax - arr[R]);
                rightMax = Math.max(rightMax, arr[R--]);
            }
        }
        return res;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr));
    }
}
posted @ 2023-11-23 22:03  Vivid-BinGo  阅读(4)  评论(0编辑  收藏  举报