程序员代码面试指南 —— 栈和队列(三)

注:题目来自于《程序员代码面试指南:IT名企算法与数据结构题目最优解》,该书是左程云老师的著作,值得推荐,这里仅是记录一下该书中题目的解法和个人理解

题目一:生成窗口最大值数组
  问题描述:
  有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置
  例如,数组为[4,3,5,4,3,3,6,7],窗口的大小为3时:
  4 3 5 4 3 3 6 7 窗口的最大值为5
  4 3 5 4 3 3 6 7 窗口的最大值为5
  4 3 5 4 3 3 6 7 窗口的最大值为5
  4 3 5 4 3 3 6 7 窗口的最大值为4
  4 3 5 4 3 3 6 7 窗口的最大值为6
  4 3 5 4 3 3 6 7 窗口的最大值为7
  如果数组长度为n,创库大小为w,则一共产生n-w+1个窗口的最大值
请实现一个函数
  输入:整形数组arr,窗口大小为w
  输出:一个长度为n-w+1的数组res,res[i]表示每一种窗口状态下的最大值
以本题为例,结果应该返回{5,5,5,4,6,7}
思路:
  可以设计一个辅助双向队列(LinkedList),队首值为滑块中的最大值。遍历数组时先入队,排除队内小于入队值的元素,队内记录位置,不记录值,这样可以判断队中的值何时失效(滑块已经滑过了),失效的值从队首出队,得到的最大值,也从队首出队。
图解:
在这里插入图片描述
代码:

public class SlidingWindow {
  public static void main(String[] args) {
    int[] arr = {4, 3, 5, 4, 3, 3, 6, 7};
    int w = 3;
    int[] res = getMaxWindow(arr, w);
    System.out.println(Arrays.toString(res));
  }

  private static int[] getMaxWindow(int[] arr, int w) {
    // 过滤出一些不符合逻辑的参数
    if (arr == null || w < 1 || arr.length < w) {
      return null;
    }
    LinkedList<Integer> qmax = new LinkedList<>();
    int[] res = new int[arr.length - w + 1];
    int index = 0;
    for (int i = 0;i<arr.length;i++){
        while (!qmax.isEmpty() && arr[qmax.peekLast()]<= arr[i]){
            qmax.pollLast();
        }
        qmax.addLast(i);
        //过期了(滑块已滑过)
        if(qmax.peekFirst() == i-w){
            qmax.pollFirst();
        }if(i >= w-1){
            //从滑块开始位置起,每次移动滑块,取队首值
            res[index++] = arr[qmax.peekFirst()];
        }
    }
    return res;
  }
}

测试结果,亲测可用:

[5, 5, 5, 4, 6, 7]

题目二:打印两个有序链表中的公共部分
题目描述:
  给定两个有序链表的头指针head1和head2,打印这两个链表中的公共部分
思路:
  因为是有序序列,所以可以比较两个链表头指针的值,值较小的,指针后移,值相等,开始打印链表,值不相等时结束。若head1 或head2有一个移动到null,循环结束
图解:
在这里插入图片描述

代码:
链表类:

public class Node {
    public int value;
    public Node next;
    public Node(int data){
        this.value = data;
    }
}

测试类及代码:

public class CommonPart {
  public static void main(String[] args) {
    Node head1 = new Node(1);
    Node node1 = new Node(3);
    Node node2 = new Node(4);
    Node node3 = new Node(4);
    Node node4 = new Node(6);
    head1.next = node1;
    node1.next = node2;
    node2.next = node3;
    node3.next = node4;

    Node head2 = new Node(2);
    Node node5 = new Node(3);
    Node node6 = new Node(4);
    Node node7 = new Node(8);
    Node node8 = new Node(9);
    head2.next = node5;
    node5.next = node6;
    node6.next = node7;
    node7.next = node8;

    printCommonPart(head1, head2);
  }

  private static void printCommonPart(Node head1, Node head2) {
    System.out.print("common is"+" ");
    if (head1 == null || head2 == null) {
      return;
    }
    while (head1 != null && head2 != null) {
      if (head1.value < head2.value) {
        head1 = head1.next;
      } else if (head1.value > head2.value) {
        head2 = head2.next;
      } else {
        System.out.print(head1.value + " ");
        head1 = head1.next;
        head2 = head2.next;
      }
    }
  }
}

测试结果,亲测可用:

common is 3 4

猜你喜欢

转载自blog.csdn.net/Kirito19970409/article/details/83788798