剑指offer打卡day20:从尾到头打印链表 (从 List 到 Stack )

题目描述

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

示例1

输入

{67,0,24,58}

返回值

[58,24,0,67]

解析:

  • 仔细观察题目:不难发现这是考察先进后出的概念。因此我们可以用栈这种典型的FILO的数据结构

    • 借助辅助栈,遍历链表,并push到栈中,然后pop至ArrayList返回即可。

      详见解法一

  • 借助Stack完成之后感觉有点索然无味,好像用的太顺手反而有点没学到东西。

    • 那看看Stack中 pop 和 push 源码吧

      public E push(E item) {
          addElement(item);
          return item;
      }
      
      public synchronized E pop() {
          E       obj;
          int     len = size();
          obj = peek();
          removeElementAt(len - 1);
          return obj;
      }
      
    • 而Stack是Vector这种动态数组,上面addElement()removeElementAt()方法都是在Vector中实现了,因此对于本题也是可以用动态数组来完成,那正好有ArrayList我们就用ArrayList吧。(详见解法二

解答:

  • 先定义个ListNode
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
    /**
       * 方便debug的toString()
       * @return
       */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        ListNode node = this;
        sb.append(node.val);
        while (node.next != null) {
            sb.append("->");
            sb.append(node.next.val);
            node = node.next;
        }
        return String.valueOf(sb);
    }
}
  • 测试类:
@Test
public void ttest1(){
    ListNode Node_head = new ListNode(67);
    ListNode Node_1 = new ListNode(0);
    ListNode Node_2 = new ListNode(24);
    ListNode Node_3 = new ListNode(58);
    Node_head.next = Node_1;
    Node_1.next = Node_2;
    Node_2.next = Node_3;
    System.out.println("Original list:"+Node_head);

    ArrayList<Integer> list = printListFromTailToHead_DynamicArray(Node_head);
    System.out.println("Dynamic Array:"+list);

    ArrayList<Integer> list_stack = printListFromTailToHead_WithStack(Node_head);
    System.out.println("WithStack :"+list);


}

/**
     * 解法一:用辅助Stack
     * @param listNode
     * @return
     */
public ArrayList<Integer> printListFromTailToHead_WithStack(ListNode listNode) {
    ArrayList<Integer> list = new ArrayList<Integer>();
    Stack<Integer> s = new Stack<Integer>();
    while(listNode!=null) {
        s.push(listNode.val);
        listNode = listNode.next;
    }
    while(!s.isEmpty()) {
        list.add(s.pop());
    }
    return list;
}

/**
     * 解法二:用动态数组,此处直接用ArrayList
     * @param listNode
     * @return
     */
public ArrayList<Integer> printListFromTailToHead_DynamicArray(ListNode listNode){
    ArrayList<Integer> result = new ArrayList<Integer>();
    if (listNode == null){
        return  result;
    }else {
        while (listNode != null){
            result.add(0,listNode.val);
            listNode= listNode.next;
        }
        return result;
    }
}
  • 输出:

    Original list:67->0->24->58
    Dynamic Array:[58, 24, 0, 67]
    WithStack :[58, 24, 0, 67]
    

附:

  • 用动态数组ArrayList来实现Stack

    当然用LinkedList会更方便点

    public class TestMyStack {
    
        //1借助ArrayList 类中的方法实现栈
        public class MyStackWithArrayList {
            private ArrayList<Object> li = new ArrayList<Object>();
            //1构造方法
            public MyStackWithArrayList(){
    
            }
    
            //2出栈
            public Object pop(){
                if(isEmpty()){
                    throw new EmptyStackException();
                }
                return li.remove(0);
            }
    
            //3进栈
            public void push(Object obj){
                li.add(0,obj);
            }
    
            //4清空
            public void clear() {
                li.clear();
            }
            //5判断是否为空
            public boolean isEmpty(){
                return li.isEmpty();
            }
    
            //6 将对象转换成字符串
            public String toString(){
                return li.toString();
            }
    
            //7返回栈口元素
            public Object peek(){
                if(isEmpty()){
                    throw new EmptyStackException();
                }
                return li.get(0);
    
            }
        }
    
    
        @Test
        public void  testMyStack(){
            MyStackWithArrayList stack=new MyStackWithArrayList();
            //进栈
            stack.push("a");
            stack.push("b");
            stack.push("c");
            stack.push("d");
            //出栈
            System.out.println(stack.pop());        //d
            //返回栈口元素
            System.out.println(stack.peek());       // c
        }
    }
    
  • 最近工作中老是遇到端口被占用的情况(xxxx is already in use)

    解决方法如下,打开cmd,两行代码搞定

    • 以占用1099为例:

      • 找到端口号:
      netstat -aon | findstr 1099
      

      使用1099的进程号为2894

      • 杀进程:
      taskkill -f -pid 2894 
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值