剑指 Offer 06. 从尾到头打印链表 【JAVA - 链表 - 栈 】

题目:
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例1:
输入:head = [1,3,2]
输出:[2,3,1]

当然第一步是跟着书上所说的根据栈“先进后出”的特点使用栈,顺便学习一下栈Stack的使用。

1.【栈实现】核心代码:
执行用时:2 ms,在所有 Java 提交中击败了19.2%的用户。

    public int[] reversePrint(ListNode head) {
    	
    	Stack<Integer> st = new Stack<Integer>(); 
  
    	ListNode cur = head;  	
    	int count = 0;
    	while(cur != null) {
    		st.push(cur.val);
    		cur = cur.next;
    		count++;
    	}
    	
    	int [] arr = new int[count];  
    	count = 0;
    	while(!st.empty()) {
    		arr[count] = st.pop();
    		count++;
    	}
    	
    	return  arr;
    }

但是其实有更快的方法。

2.【反转数组】核心代码:
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户。

//反转链表 [反转数组]
    public int[] reversePrint(ListNode head) {
    
    	ListNode cur = head;  	
    	int count = 0;
    	while(cur != null) {
    		cur = cur.next;
    		count++;
    	}
    	
    	int [] arr = new int[count];  
    	cur = head;  
    	for(int i = count-1 ; i >= 0 ;i--) {
    		arr[i] = cur.val;
    		cur = cur.next;
    	}
    	
    	return  arr;
    }

总结一下:学习这一节时,主要学习了JAVA写单链表,以及JAVA如何使用栈。(因为书上使用的是C++,所以需要去参考其他资料)

JAVA写单链表参考:http://t.csdn.cn/S5XGL
JAVA使用栈参考:http://t.csdn.cn/dI6VN

关于做这个题所留下的全部代码,包括java栈的定义、增加节点、删除节点等(全部通过测试,但是完成它用了一天时间呜呜呜):

import java.util.Stack;

public class LinkedNode {
	
	//定义题目中给出的节点
	public class ListNode {
		int val;
		ListNode next;
		
		ListNode(int x) { 
			val = x; 
		}

		ListNode(int val, ListNode next) {
			this.val = val;
			this.next = next;
		}
	}
	
	private ListNode head; //头结点
	private int size; //链表长度
	
	//初始化链表 构造函数
	public LinkedNode() {
		this.head = null ; 
		this.size = 0;
	}
	
	//得到链表的长度
	public int getSize() {
		return this.size;
	}
	
	//链表头部添加元素
	public void addBefore(int val) {
		//头结点
		ListNode node =  new ListNode(val);
		node.next = this.head ; 
		this.head = node ;
		this.size++;
	}
	
	//链表中间插入元素
	public void add(int val , int index) {
	
		if(index < 0 || index > this.size) {System.out.print("index错误");return ;}
		
		if(index == 0) {
			addBefore(val);
		}else {
			
			ListNode pre = this.head;

			for(int i = 0; i< index -1 ; i ++) {
				pre = pre.next;
			}
			
			ListNode node =  new ListNode(val);
			node.next = pre.next;
			pre.next = node;
			this.size++;
			
		}	
	}
	
	//链表尾部插入元素
	public void addLast(int val) {
		add(val , this.size);
	}
	
	//删除指定(值)元素
	public void delete(int elem) {
		
		if(this.head == null) {System.out.print("没有元素可以删除"); return ;}
		
		if(this.head.val == elem) {
			this.head = this.head.next ;
			this.size--;
		}else {
			ListNode cur = this.head;
			while(cur.next != null) {
				if(cur.next.val == elem) {cur.next = cur.next.next; this.size--;}
				else cur = cur.next ;
			}
		}
		
	}
	
	//删除第一个元素
	public int deleteFirst() {
		
		if(this.head == null) {System.out.print("没有元素可以删除"); return -1;}
		
		ListNode node = this.head ;
		this.head = this.head.next;
		node.next=null;
		this.size--;
		return node.val;
	}
	
	//删除最后一个元素
	public int deleteLast() {
		
		if(this.head == null) {System.out.print("没有元素可以删除"); return -1;}
		
		if(this.getSize() == 1) {
			return this.deleteFirst();
		}else {
			ListNode pre = this.head;
			ListNode cur = this.head;
			while(cur.next != null) {
				pre = cur ;
				cur = cur.next;
			}
			pre.next = cur.next;
			this.size--;
			return cur.val;
		}
	}
	
	//虚构头结点删除元素
	public void deleteByImagine(int elem) {
		ListNode imaNode = new ListNode(-1 , this.head);
		ListNode cur = imaNode;
		
		while(cur.next != null) {
			if(cur.next.val == elem) { cur.next = cur.next.next;this.size--;}
			else cur = cur.next;
		}
		
		//去除虚节点
		this.head = imaNode.next;
	}
	
	//虚构头结点插入元素
	public void insertByImagine(int val , int elem) {
		
		ListNode imaNode = new ListNode(-1 , this.head);
		ListNode pre = imaNode;
	
		while(pre.next != null) {
			if(pre.next.val == elem) {
				ListNode node = new ListNode(val);
				node.next = pre.next;
				pre.next = node;
				this.size++;
				break;
			}else {
				pre = pre.next;
			}
		}
		//去除虚节点
		this.head = imaNode.next;
	}
	
	
	//反转链表[栈]
//    public int[] reversePrint(ListNode head) {
//    	
//		Stack<Integer> st = new Stack<Integer>(); 
//	
//		ListNode cur = head;  	
//		int count = 0;
//		while(cur != null) {
//			st.push(cur.val);
//			cur = cur.next;
//			count++;
//		}
//		
//		int [] arr = new int[count];  
//		count = 0;
//		while(!st.empty()) {
//			arr[count] = st.pop();
//			count++;
//		}
//		
//		return  arr;
//	}

	//反转链表 [反转数组]
    public int[] reversePrint(ListNode head) {
    
    	ListNode cur = head;  	
    	int count = 0;
    	while(cur != null) {
    		cur = cur.next;
    		count++;
    	}
    	
    	int [] arr = new int[count];  
    	cur = head;  
    	for(int i = count-1 ; i >= 0 ;i--) {
    		arr[i] = cur.val;
    		cur = cur.next;
    	}
    	
    	return  arr;
    }
    
    //重写链表的输出方法
    @Override
    public String toString() {
    	StringBuffer sb = new StringBuffer();
    	ListNode cur = this.head;
    	while(cur != null) {
    		sb.append(cur.val +"->");
    		cur = cur.next;
    	}
    	sb.append("NULL");
		return sb.toString();
    	
    }
    
    
    public static void main(String[] args) {
   
    	LinkedNode node = new LinkedNode();
    	//定义空链表
    	LinkedNode node1 = new LinkedNode();
    
    	//添加
    	for(int i = 0 ; i< 10 ; i++) {
    		node.addBefore(i); 		
    	}
    	
    	System.out.print(node);
    	
    	node.addBefore(3);
    	System.out.print("\n"+node);
    	
    	node.addLast(5);
    	System.out.print("\n"+node);
    	
    	node.add(10, 5);
    	System.out.print("\n"+node);
    	
    	node.delete(10);
    	System.out.print("\n"+node);
    	
    	node.deleteFirst();
    	System.out.print("\n"+node);
    	
    	node.deleteLast();
    	System.out.print("\n"+node);
    	
    	node.deleteByImagine(0);
    	System.out.print("\n"+node);
    	
    	node.insertByImagine(11, 8);
    	System.out.print("\n"+node+"\n" + "@@@@");
    	
    	for(int i = 0 ;i < node.size ; i++) {
    		System.out.print(node.reversePrint(node.head)[i] + "->");
    	}
    	
    	for(int i = 0 ;i < node1.size ; i++) {
    		System.out.print("\n"+"@@@"+node1.reversePrint(node1.head)[i] + "->");
    	}
   
    }
	
}

最后,链表真的好难!!!!!!!!!!!😭😭😭😭😭😭😭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值