9. Note algorithm beautiful linear structure: lists, linked lists, stacks, queues

9. The linear structure: lists, linked lists, stacks, queues

1. Object-oriented concepts

Classes and Objects

  • Object and operation data packaged together, all of this class are described

  • Created (instantiated) by the object constructor

  • The relationship between class and class

    • Association (combination, aggregation)

    • Generalization

About inheritance

  • Ancestor class Object Java ancestor class of all classes
  • Method overrides
  • toString method
  • equals method

About Interface

  • Comparable interface

  • Comparator interface

  • Cloneable interface

  • Serializable Interface

public class Teacher {
  private String name;
  private int ability;
  private Student[] students;
}
public class Student {
  protected String name;
  public int getAge() {
    return age;
  }
  protected int age;
  protected int ability;
  private Teacher teacher;
  public Student(String name, int age) {
    this.name = name;
    this.age = age;
  }
  public void study() {
    ability++;
  }
  @Override
  public String toString() {
    return "Student{" +
        "name='" + name + '\'' +
        ", age=" + age +
        ", ability=" + ability +
        '}';
  }
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Student student = (Student) o;
    return name.equals(student.name);
  }
  @Override
  public int hashCode() {
    return name.hashCode();
  }
  public static void main(String[] args) {
    Student stu1 = new Student("唐僧", 200);
    Student stu3 = new Student("唐僧", 200);
    Student stu2 = new Student("悟空", 600);
    stu1.study();
    stu1.study();
    stu2.study();
    System.out.println(stu1.toString());
    System.out.println(stu2.toString());
    System.out.println(stu1.equals(stu3));
  }
}
public class CleverStudent extends Student {
  public CleverStudent(String name, int age) {
    super(name, age);
  }
  @Override
  public void study() {
    // super.study();
    // super.study();
    ability += 2;
  }
  public void study(int s) {
    ability += s;
  }
}

2. Data Structure Overview

  • Data (data)
    • Everything can be entered into the computer and all data can be processed
  • Data element (data element)

  • Data object (data object)

Logical structure

  • Collection: elements listed together

  • Linear structure: successive longitudinal elements (correspondence)

  • Tree: the presence of many relationship elements

  • FIG structure or a network structure: many relationship exists between the elements

Storage structure

  • Sequentially storing: consecutive addresses, with the array

  • Chain storage: address discontinuities with a pointer (reference, object-oriented)

For some special needs, specifically designed for data storage

3. List

Interface definition list

List -MyArrayList achieve an array

Linked list implementation (single chain, double chain)

Iterator

Generics

Java List API

import java.util.*;
public class ListDemo {
  public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list = new LinkedList<>();
    list.add("adnda");
    list.add("xyz");
    list.add("def");
    list.remove("");
    //  ......
    Collections.sort(list);//可以直接排序,api已经定义字符串比较
    List<Student> list1 = new ArrayList<>();
    list1.add(new Student("zhangsan", 10));
    list1.add(new Student("lsii", 20));
    list1.add(new Student("wangwu", 40));
    list1.add(new Student("wangsu", 30));
    Collections.sort(list1, (o1, o2) -> {//这里可以在Student中实现Comparable接口,后者给Collections第二个参数传比较器
      return o1.getAge() - o2.getAge();
    });
    Iterator<Student> iterator = list1.iterator();//迭代器.hasNext()和.next()
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }
}

Bucket sort

package org.lanqiao.algo.elementary.datastructure;
/**
 * 简单单向链表的节点
 */
public class LinkedNode {
  public int value;
  public LinkedNode next;
  public LinkedNode(int value) {
    this.value = value;
  }
}
package org.lanqiao.algo.elementary._03sort;
import org.assertj.core.api.Assertions;
import org.lanqiao.algo.elementary.datastructure.LinkedNode;
import org.lanqiao.algo.util.Util;
import java.util.Arrays;
/**
 * 桶排序<br />
 * 思路:见http://www.cs.usfca.edu/~galles/visualization/BucketSort.html<br />
 * 工作的原理是将数组分到有限数量的桶子里。<br />
 * 每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。<br />
 * 桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。<br />
 * 但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。<br />
 *
 * 时间复杂度: O(N+C),其中C=N*(logN-logM)<br />
 * 空间复杂度:N+M,M为桶的个数<br />
 * 非原址排序<br />
 * 稳定性:稳定<br />
 *
 * 桶排序假设数据会均匀入桶,在这个前提下,桶排序很快!
 */
public class _9BucketSort {
    // 根据桶的个数来确定hash函数,这份代码适合桶的个数等于数组长度
    private static int hash(int element, int max, int length) {
        return (element * length) / (max + 1);
    }
    public static void main(String[] args) {
        int[] arr = Util.getRandomArr( 10, 1, 100 );
        System.out.println( "begin..." + Arrays.toString( arr ) );
        new _9BucketSort().sort( arr );
        System.out.println( "final..." + Arrays.toString( arr ) );
        Assertions.assertThat( Util.checkOrdered( arr, true ) ).isTrue();
    }
    private void sort(int[] arr) {
        int length = arr.length;
        LinkedNode[] bucket = new LinkedNode[length];  // 桶的个数=length
        int max = Util.maxOf(arr);//求max
        // 入桶
        for (int i = 0; i < length; i++) {
            int value = arr[i];//扫描每个元素
            int hash = hash( arr[i], max, length ); // 桶的下标
            if (bucket[hash] == null) {
                bucket[hash] = new LinkedNode( value ); // 初始化链表表头
            } else {
                insertInto( value, bucket[hash], bucket, hash ); // 插入链表
            }
        }

        int k = 0; // 记录数组下标
        //出桶,回填arr
        for (LinkedNode node : bucket) {
            if (node != null) {
                while (node != null) {
                    arr[k++] = node.value;
                    node = node.next;
                }
            }
        }
    }
    private void insertInto(int value, LinkedNode head, LinkedNode[] bucket, int hash) {
        LinkedNode newNode = new LinkedNode( value );
        //小于头节点,放在头上
        if (value <= head.value) {
            newNode.next = head;
            // 替换头节点
            bucket[hash] = newNode;
            return;
        }
        /*往后找第一个比当前值大的节点,放在这个节点的前面*/
        LinkedNode p = head;
        LinkedNode pre = p;
        while (p != null && value > p.value) {
            pre = p;
            p = p.next;
        }
        if (p == null) { // 跑到末尾了
            pre.next = newNode;
        } else { // 插入pre和p之间
            pre.next = newNode;
            newNode.next = p;
        }
    }
}

Question 1: Remove duplicate node

Coding, repeating node removes the list is not sorted. The most reserved node began to emerge.

Example 1:

 输入:[1, 2, 3, 3, 2, 1]
 输出:[1, 2, 3]

Example 2:

 输入:[1, 1, 1, 1, 2]
 输出:[1, 2]

prompt:

  1. Chain length in the range [0, 20000].
  2. List elements in the range [0, 20000].
public static ListNode removeDuplicateNodes(ListNode head) {
    ListNode p=head;
    ListNode pre=null;
    Set<Integer> set=new HashSet<Integer>();
    while(p!=null){
        if(set.contains(p.val)){//如果存在就删除,前面的next指向后面的
            pre.next=p.next;//此时pre不动
        }else {
            pre=p;//pre变为当前
            set.add(p.val);
        }
        p=p.next;//两种情况都要p指向后面,
    }
    return head;
}

Topic Link

Question 2: Return penultimate k nodes

Implement an algorithm to find out the check list in the penultimate k nodes. The return value of the node.

Note: This problem is relatively minor changes to the original title

Example:

输入: 1->2->3->4->5 和 k = 2
输出: 4

Description:

Given k guaranteed to be effective.

public static int kthToLast(ListNode head, int k) {
    //由于题目中k保证有效,如果不保证开头要设置
    ListNode pre=head;
    ListNode now=head;
    int count=1;
    while(count<k){//now指针不断后移动,移动k-1次
        now=now.next;
        count++;
    }
    //此时pre指向第一个元素,now指向第k个元素
    while(now.next!=null){//如果now.next为null,倒数k个元素就为第一个元素
        pre=pre.next;//否则两者共同往后移动
        now=now.next;
    }
    return pre.val;
}

Topic Link

Problem 3: Remove the intermediate node

Implement an algorithm to remove a node in the middle of a one-way linked list (except for the first and last node, it is not necessarily an intermediate node), assuming that you can only access the node.

Example:

输入:单向链表a->b->c->d->e->f中的节点c
结果:不返回任何数据,但该链表变为a->b->d->e->f
public static void deleteNode(ListNode node) {
    node.val=node.next.val;//后面元素的值覆盖当前元素,后面的元素成为当前元素
    node.next=node.next.next;//当前元素的next指向后面的后面元素
}

Topic Link

Question 4: segmentation list

Write code, a given value of x is divided into two parts, reference will list all less than x nodes ahead of node x greater than or equal to
a given a list head pointer ListNode node, return to the list rearranged the head pointer.

Note: Keep the original data sequence unchanged after the split.

Example:

输入: head = 3->5->8->5->10->2->1, x = 5
输出: 3->2->1->5->8->5->10
/* 将链表头节点和其节点值传递到分割链表 */
public static ListNode partition(ListNode node, int x) {
    ListNode beforeStart = null;//前半部分
    ListNode beforeEnd = null;//前半部分最后一个元素
    ListNode afterStart = null;//后半部分
    ListNode afterEnd = null;//后半部分最后一个元素
    /* 分割链表 */
    while (node != null) {
        ListNode next = node.next;//先保存当前节点的next
        node.next = null;
        if (node.val < x) {
            /* 将节点插入到before 链表尾部 */
            if(beforeStart == null){//没有节点
                beforeStart = node;//前半部分头为node
                beforeEnd = beforeStart;//前半部分尾为node
            }else{
                beforeEnd.next = node;
                beforeEnd = node;
            }
        }else{
            /* 将节点插入到after 链表尾部 */
            if(afterStart == null) {
                afterStart = node;
                afterEnd = afterStart;
            }else{
                afterEnd.next = node;
                afterEnd = node;
            }
        }
        node = next;
    }
    if (beforeStart == null) {
        return afterStart;
    }
    /* 合并after 链表和before 链表 */
    beforeEnd.next = afterStart;
    return beforeStart;
}

Topic Link

5 questions: summing list

Given two integers a linked list representation, each node contains a digit.

These digits are stored in reverse, which is a bit in the header row of the list.

Write a function sum of these two integers, and returns the result as a linked list.

Example:

输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295
输出:2 -> 1 -> 9,即912

Advanced: assuming that these digits are stored forward, please do it again.

Example:

输入:(6 -> 1 -> 7) + (2 -> 9 -> 5),即617 + 295
输出:9 -> 1 -> 2,即912
public static ListNode addTwoNumbers(ListNode l1, ListNode l2,int value) {
    if(l1==null&&l2==null&&value==0){
        return null;
    }
    int sum=value;
    if(l1!=null){//不为空时才加入
        sum+=l1.val;
    }
    if(l2!=null){//不为空时才加入
        sum+=l2.val;
    }
    ListNode list=new ListNode(sum%10);
    list.next=addTwoNumbers(l1==null?null:l1.next,l2==null?null:l2.next,sum/10);
    //这里需要判断是否l1和l2是否为空
    return list;
}
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    return addTwoNumbers(l1,l2,0);
}

Topic Link

Question 6: Loop Detection

Given a list loop, the algorithm returns to realize a loop at the beginning of the node.
A cycloalkyl list definition: the next element in the list point to a node in the node preceding it had occurred, it indicates the presence of the chain loop. Example:
Input: A -> B -> C -> D -> E -> C (C node appears twice)
Output: C

If there is a loop return loop node, or null if there is no loop

Part 1: detecting whether there is a loop chain

Detect whether there is a loop list, there is a simple approach called FastRunner / SlowRunner law. FastRunner a move two steps forward, one step and SlowRunner once. This is like two cars around the track with a forward at different speeds, would ultimately come together.

A careful reader may ask: FastRunner will not just "crossed" SlowRunner, without colliding happen? Impossible. Suppose FastRunner really crossed SlowRunner, and SlowRunner at position i, FastRunner at position i + 1. So, in the previous step, SlowRunner is in position i-1, FastRunner in position ((i + 1) -2) or i-1, that is, the two touched together.

FastPointer moving speed is twice SlowPointer of. When SlowPointer gone k nodes into the loop, the loop k FastPointer has entered the list of nodes, that is to say FastPointer and SlowPointer apart LOOP_SIZE-k nodes.

Next, if SlowPointer at every node, FastPointer left two nodes, every time, the distance between the two will be closer to a node. Thus, after step SlowPointer take LOOP_SIZE-k, FastPointer take 2 * (LOOP_SIZE-k), they will touch together. In this case the distance between the two loop start with k nodes.

List header at the beginning of the loop are within a k nodes. Thus, if a pointer which remains constant, a further pointer to the list header, then the two pointers will meet at the beginning of the loop.

According to Section 2, 3, you can directly export the following algorithm.

(1) create two pointers: FastPointer and SlowPointer.

(2) SlowPointer every step, FastPointer go two steps.

(3) when the two touch together, the point SlowPointer LinkedListHead, FastPointer remains unchanged.

(4) move at the same speed and SlowPointer FastPointer, one step, and then returns the new collision.

public static ListNode detectCycle(ListNode head) {
    ListNode p=head;
    HashSet set=new HashSet();
    while(true){
        if(set.contains(p)||p==null){//如果head为null,p刚开始就为null,直接返回null
            //或者p已经在集合中
            return p;
        }else{
            set.add(p);
            if(p.next==null){//p已经是最后一个了,直接返回null
                return null;
            }
            p=p.next;
        }
    }
}
ListNode detectCycle2(ListNode head) {
    ListNode slow = head;
    ListNode fast = head;
    /* 找到相汇处。LOOP_SIZE - k 步后会进入链表 */
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
        if (slow == fast) { // 碰在一起
            break;
        }
    }
    /* 错误检查——若无相汇处,则无环路 */
    if (fast == null || fast.next == null) {
        return null;
    }
    /* 将慢的移动至头节点。两者均距离起始处k 步。
        * 若两者以相同速度移动,则必然在环路起始处相遇 */
    slow = head;
    while (slow != fast) {
        slow = slow.next;
        fast = fast.next;
    }
    /* 两者均指向环路起始处 */
    return fast;
}

Topic Link

Question 7: palindrome list

Write a function that checks whether an input list is a palindrome.

Example 1:

输入: 1->2
输出: false 

Example 2:

输入: 1->2->2->1
输出: true 

Solution 1: Comparative inverted and
the first solution is to reverse the entire list, and then comparing the original list and the list reverse. If they are identical, then the list is palindromic.
Note that when you compare the original list and reverse a linked list, in fact, just compare the list of the first half. If the first part of the original list and reversal of the same list, then certainly the second half both the same.

public static ListNode reverse(ListNode node){
    ListNode head=null;//保存投的引用
    while(node!=null){
        ListNode n=new ListNode(node.val);//创建新的头
        //往前插入
        n.next=head;//由于依次往前插入,新的头的next为原来的头head
        head=n;//n变为新的头
        node=node.next;//指向下一个元素
    }
    return head;//如果本来就为null,head也为null
}
public static boolean isEqual(ListNode l1,ListNode l2){
    while(l1!=null&&l2!=null){
        if(l1.val!=l2.val){
            return false;
        }
        l1=l1.next;//下一个为null时候,循环判断会结束
        l2=l2.next;
    }
    return l1==null&&l2==null;//如果一开始两个都为空,返回true,否则false
}
public static boolean isPalindrome(ListNode head) {
    ListNode t=reverse(head);
    return isEqual(t,head);
}

Solution 2: iterative method for
the first half of the list in order to check whether the reversal from the second half, how to do it? Simply reversing the first half of the list, it can be implemented using the stack.
The first half of the required stack node. The chain length is known or not, there are two ways the stack.

  • If the chain length is known to be a standard for loop iterates the front half of the node, each node stack. Of course, careful treatment chain length is an odd number.

  • If the chain length is unknown, the method may be utilized runner speed described iterates beginning of the chapter list. In each iteration of the loop, the slow runner in the data stack. At the tail of the list fast runner arrived, slow runner is located just off the middle of the list. At this point, the stack to store all the nodes in the front half of the list, but the order is reversed. Next, simply iterate over the list the remaining nodes. At each iteration, comparing the current node and the top element, if the comparison result is identical ITERATIVE, the palindromic sequence list.

public static boolean isPalindrome2(ListNode head) {
    ListNode fast=head;
    ListNode slow=head;
    Stack<Integer> stack=new Stack<Integer>();
    while(fast!=null&&fast.next!=null){
        stack.push(slow.val);
        slow=slow.next;
        fast=fast.next.next;
    }
    //若个数为奇数,fast在最后一个元素。slow在最中间。例如1,2,3移动一次后
    //若个数为偶数,fast为null,slow在中间偏右一个 ,例如1,2,3,4移动两次后
    if(fast!=null){
        slow=slow.next;
    }
    while(slow!=null){
        if(slow.val!=stack.pop()){
            return false;
        }
        slow=slow.next;
    }
    return true;
}

Topic Link

Defined stack

  • Stack (Stack), also known as the stack, it is the operation is limited to the linear form, with the restriction that only allows for insertions and deletions at one end of the table, does not allow any other position of the insertion, search, and delete operations.

  • One end of the table insert, delete operation called stack (Top), the top element is referred to save the top element . In contrast, another table - called end bottom of stack (bottom).

  • When the stack is no data elements are referred to empty stack ; a stack in one element yet inserted into the stack or the stack ; remove elements from the stack, also known as a pop or de-stacked .

  • Since the stack only insertion and deletion operations in the stack, the stack elements must first backward out of the stack, so the stack is again referred LIFO table (Last In First Out, referred LIFO).

The definition of the queue

  • Queue (Queue), with the stack as it is also a linear table operation is limited , which limitation is only permitted in the table insertion end , the table in deleting the other end . One end is inserted into one end of the queue is called the tail of data elements, data elements referred to delete the first team

  • Referred to the tail element inserted into the team or the team , the new element as a new element of the tail after enqueuing; referred to remove elements from the queue leave or dequeued , the dequeue elements, which subsequent elements to become the new head of the queue element

  • Since the insert and delete operations queue are the first team in the tail and each element is bound to enter the order of leaving the team, that team advanced elements will inevitably leave first, so called for the FIFO queue table (First In First Out , referred to as FIFO). Queue structure and daily life queued service model is consistent, people first to enter the queue, and the first service was first leave from the team; the arrival of the last man to be the last of the queue, and finally get the service and the last to leave

Question 8: an array to achieve the three stacks

triple. It describes how to implement an array with only three stacks

And many issues, the solution of this problem basically depends on what you want to stack the level of support. If each stack space allocated a fixed, will be able to meet the needs, so did that is. However, to do so, which may have a stack space is not enough, the other stack is almost empty.
Another approach is flexible in the stack space allocation, but that way, the complexity of this problem will be greatly increased.

Topic Link

Question 9: stack minimum.

Please a stack design, in addition to push and pop functions, also supports the min function that returns the minimum value of the stack elements. Performing push, pop operations and min time complexity must be O (1).

push (5); // stack is {5}, the minimum is 5
Push (6); // stack is {6, 5}, the minimum is 5
Push (3); // stack of {3, 6, 5}, the minimum is 3
Push (7); // stack is {7, 3, 6, 5}, the minimum is 3
pOP (); // 7 pop, the stack is {3, 6, 5}, the minimum is 3
pOP (); // 3 pop, the stack is {6, 5}, the minimum is 5
to observe, when the stack back to the previous state before ({6, 5}), the minimum value of the returned state (5), which is derived our second solution.
As long as the record minimum in each state, to obtain the minimum value is a piece of cake. Implementation is very simple, each node can record the current minimum. This way, you want to find min, directly view the top element will be able to get the minimum. When a stack element, the element will remember the current minimum value, min will be recorded in the min data structure member itself.

static class MinStack {
    Stack<Integer> stack;
    int minV=Integer.MAX_VALUE;
    Stack<Integer> min;
    /** initialize your data structure here. */
    public MinStack() {
        stack=new Stack<Integer>();
        min=new Stack<Integer>();//当当前最小值改变时,记录最小值
    }
    public void push(int x) {
        if(x<=minV||stack.empty()){//若压入的元素小于等于最小元素,压入min,或者为空时
            min.push(x);
            minV=x;
        }
        stack.push(x);
    }

    public void pop() {
        if(stack.peek()==minV){//弹出最小元素可能改变最小值
            min.pop();
            if(min.empty()){
                minV=Integer.MAX_VALUE;
            }else{
                minV=min.peek();//重新设置最小元素
            }
        }
        stack.pop();
    }

    public int top() {
        return stack.peek();
    }

    public int getMin() {
        return min.peek();
    }
}

Topic Link

10 questions: Heap plate

Heap dish. Imagine a pile of plates, the stack too high may fall down. Therefore, in real life, when the plate heap to a certain height, we will be another pile of dishes. Please realize the data structure SetOfStacksto simulate this behavior. SetOfStacksIt should be composed of a plurality of stacks, and a new front stack when a stack fills. In addition, SetOfStacks.push()and SetOfStacks.pop()it should be the same as the ordinary stack operation method (that is to say, pop the returned value (), should the case when only one with the same stack). Advanced: implement a popAt(int index)method, according to the specified sub-stack performs a pop operation.

When a stack is empty, the stack should be deleted. When the stack without the stack element or absent pop, popAtshould return -1.

Example 1:

 输入:
["StackOfPlates", "push", "push", "popAt", "pop", "pop"]
[[1], [1], [2], [1], [], []]
 输出:
[null, null, null, 2, 1, -1]

Example 2:

 输入:
["StackOfPlates", "push", "push", "push", "popAt", "popAt", "popAt"]
[[2], [1], [2], [3], [0], [0], [0]]
 输出:
[null, null, null, null, 2, 1, 3]
class StackOfPlates {
    private List<Stack<Integer>> stackList;
    private int cap;//初始状态含有栈的数量
    public StackOfPlates(int cap) {
        stackList = new ArrayList<Stack<Integer>>();
        this.cap = cap;
    }
    public void push(int val) {
        if (cap <= 0) {
            return;
        }
        if (stackList.isEmpty() || stackList.get(stackList.size() - 1).size() == cap) {
            Stack<Integer> stack = new Stack<Integer>();
            stack.push(val);
            stackList.add(stack);
            return;
        }
        stackList.get(stackList.size() - 1).push(val);
    }
    public int pop() {
        return popAt(stackList.size() - 1);
    }
    public int popAt(int index) {
        if (index < 0 || index >= stackList.size()) {
            return -1;
        }
        Stack<Integer> stack = stackList.get(index);//传来是引用
        if (stack.isEmpty()) {
            return -1;
        }
        int res = stack.pop();
        if (stack.isEmpty()) {
            stackList.remove(index);
        }
        return res;
    }
}

Topic Link

11 questions: of the stack for the team

MyQueue implement a class that implemented a stack with two queues.

Example:

MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

Description:

  • You can only use the standard stack operations - that is, only push to top, peek/pop from top, sizeand is emptythe operation is legal.
  • The language you are using may not support stack. You can use the list or the deque (deque) to simulate a stack, as long as a standard stack operation can.
  • Assuming that all operations are valid (e.g., not an empty queue or peek operation called pop).
  1. push when the operation can be performed directly numStack.push
  2. When the pop of the time, because we need to pop the first element inserted, therefore, we can and then with a stack, you can reverse the original stack. If helpStack herein is empty, it is necessary to remove all of the elements numStack pressed into helpStack then to pop elements from the helpStack. Otherwise, you can directly from helpStack in pop elements.
class MyQueue {
    private Stack<Integer> numStack;
    private Stack<Integer> helpStack;
    public MyQueue() {
        numStack = new Stack<Integer>();
        helpStack = new Stack<Integer>();
    }
    public void push(int x) {
        numStack.push(x);
    }
    public void move(){//numStack中的元素全部取出压入到helpStack中
        while (!numStack.isEmpty()) {
            helpStack.push(numStack.pop());
        }
    }
    public int pop() {
        if(helpStack.isEmpty()){//若helpStack为空
            move();
        }
        return helpStack.pop();
    }
    public int peek() {
        if(helpStack.isEmpty()){
            move();
        }
        return helpStack.peek();
    }
    public boolean empty() {
        return helpStack.isEmpty() && numStack.isEmpty();
    }
}

Topic Link

12 questions: Stack Sort

Stack sort. Write a program to sort the stack so that the smallest element top of the stack. You can only use a temporary stack for other data, but may not be copied to other elements of data structures (such as arrays) in. The stack supports the following pushoperations: pop, , peekand isEmpty. When the stack is empty, peekit returns -1.

Example 1:

 输入:
["SortedStack", "push", "push", "peek", "pop", "peek"]
[[], [1], [2], [], [], []]
 输出:
[null,null,null,1,null,2]

Example 2:

 输入: 
["SortedStack", "pop", "pop", "push", "pop", "isEmpty"]
[[], [], [], [1], [], []]
 输出:
[null,null,null,null,null,true]

Description:

  1. The number of elements in the stack [0, 5,000] range.

    static class SortedStack {
        Stack<Integer> stack;
        Stack<Integer> help;
        public SortedStack() {
            stack=new Stack<Integer>();
            help=new Stack<Integer>();
        }
        public void push(int val) {
            if(stack.empty()||val<=stack.peek()){//为空或者插入元素比底下小
                stack.push(val);
            }else{
                while (!stack.empty()&&val>stack.peek()){//注意不要忘记stack不为空的时候区元素
                    help.push(stack.pop());
                }
                stack.push(val);
                while(!help.empty()){
                    stack.push(help.pop());
                }
            }
        }
        public void pop() {
            if(!stack.empty()) {//注意不为空时弹出
                stack.pop();
            }
        }
        public int peek() {
            if(!stack.empty()) {//注意不为空时
                return stack.peek();
            }else {
                return -1;
            }
        }
        public boolean isEmpty() {
            return stack.isEmpty();
        }
    }

Topic Link

13 questions: Animal Shelter

Animal shelter. Home animal shelter accommodating only dogs and cats, and strict adherence to the principle of "first in first out" of. When the animal shelter adoption, the adopter can only adopt all the animals in the "oldest" (by entering the shelter of the length of time given) animals, or you can choose a cat or dog (and must adopt such animals "oldest). In other words, the adopter can not freely choose the objects to adoption. Create apply to this system data structure, to achieve a variety of methods of operation, such as enqueue, dequeueAny, dequeueDogand dequeueCat. LinkedList allows the use of Java built-in data structures.

enqueueThere is a method animalparameter animal[0]represents the number of animals, animal[1]on behalf of animal species, where 0 represents a cat, a dog behalf.

dequeue*Method returns a list [动物编号, 动物种类], if you can not adopt an animal is returned [-1,-1].

Example 1:

 输入:
["AnimalShelf", "enqueue", "enqueue", "dequeueCat", "dequeueDog", "dequeueAny"]
[[], [[0, 0]], [[1, 0]], [], [], []]
 输出:
[null,null,null,[0,0],[-1,-1],[1,0]]

Example 2:

 输入:
["AnimalShelf", "enqueue", "enqueue", "enqueue", "dequeueDog", "dequeueCat", "dequeueAny"]
[[], [[0, 0]], [[1, 0]], [[2, 1]], [], [], []]
 输出:
[null,null,null,null,[2,1],[0,0],[1,0]]

Description:

  1. The maximum capacity of accommodating 20,000

Cats and dogs by two classes divided into twoLinkedList

For dequeueAny, according to the meaning of the questions, given the number is, the smaller the number, the longer the time to get into the shelter, the more should the team

  • If this occurs both queues are empty, exhibiting catId == dogId(as if the empty return int max), then returns{-1, -1}
class AnimalShelf {
    private List<LinkedList<int[]>> data;
    private int[] initAnimal = {-1, -1};
    public AnimalShelf() {
        data = new ArrayList<>();
        data.add(new LinkedList<>());
        data.add(new LinkedList<>());
    }    
    public void enqueue(int[] animal) {
        data.get(animal[1]).addLast(animal);
    }   
    public int[] dequeueAny() {
        int catId = data.get(0).isEmpty()? Integer.MAX_VALUE : data.get(0).peekFirst()[0];
        int dogId = data.get(1).isEmpty()? Integer.MAX_VALUE : data.get(1).peekFirst()[0];
        if(catId < dogId){
            return data.get(0).pollFirst();
        }else if(dogId < catId){
            return data.get(1).pollFirst();
        }else{
            return initAnimal;
        }
    }   
   public int[] dequeueDog() {
        if(data.get(1).isEmpty()) return initAnimal;
        return data.get(1).pollFirst();
    }
    public int[] dequeueCat() {
        if(data.get(0).isEmpty()) return initAnimal;
        return data.get(0).pollFirst();
    }
}

Guess you like

Origin www.cnblogs.com/cxynb/p/12540538.html