今天继续LeetCode上的题,明天准备写写最近学的springmvc
题目一:剑指Offer上的从尾到头打印链表,就是从链表的尾部输出链表,而且用数组返回,思路是利用栈的特点,完成
public class Office06 { public static void main(String[] args) { ListNode head=null; //使用尾插法插入结点,时间复杂度有点高 for(int i=0;i<6;i++){ ListNode listNode=new ListNode(i); //判断头结点是否为空,是的话将一个节点对象赋给它,成为头节点 if(head==null){ head=listNode; }else { ListNode cur=head; //从头节点开始遍历链表,将新节点挂载到最后一个节点上 while (cur.next != null) { cur = cur.next; } cur.next=listNode; } } Solution solution=new Solution(); //注意这里不能传入头插法的链表,因为头插法的头节点是变化的,以我的理解来说它的指针指向的是屁股 solution.reversePrint(head); } } //节点对象 class ListNode{ int val; ListNode next; ListNode(int x){ val=x; } } class Solution{ //传入一个链表的头结点 public int[] reversePrint(ListNode head) { Stack<ListNode> stack=new Stack<ListNode>(); ListNode temp=head; //将链表的头结点压入栈,然后指向下个结点 while(temp!=null){ stack.push(temp); temp=temp.next; } int size=stack.size(); int[] print =new int[size]; //利用栈先进后出的特点将值一个个结点对象弹出,放入数组中,实现链表的倒序输出 for (int i=0;i<size;i++){ print[i]=stack.pop().val; System.out.print(print[i]); } return print; } }View Code
题目二:剑指Offer上的反转链表,我根据题解上作者:jyd说的迭代来完成的
public class Office24 { public static void main(String[] args) { ListNode01 head=null; //使用尾插法插入结点,时间复杂度有点高 for(int i=0;i<6;i++){ ListNode01 listNode=new ListNode01(i); //判断头结点是否为空,是的话将一个节点对象赋给它,成为头节点 if(head==null){ head=listNode; }else { ListNode01 cur=head; //从头节点开始遍历链表,将新节点挂载到最后一个节点上 while (cur.next != null) { cur = cur.next; } cur.next=listNode; } } Solution01 solution01=new Solution01(); ListNode01 listNode01=solution01.reverseList(head); //从头结点开始输出结点元素 for (int i=0;i<6;i++){ System.out.println(listNode01.val); listNode01=listNode01.next; } } } //节点对象 class ListNode01{ int val; ListNode01 next; ListNode01(int x){ val=x; } } //题目要求为链表的倒序输出,并且之前的头节点指向空 class Solution01 { public ListNode01 reverseList(ListNode01 head) { ListNode01 prev=null; ListNode01 curr=head; while (curr!=null){ //存储当前结点的下个结点,为中间变量 ListNode01 temp=curr.next; //将当前结点的下个结点变成它的前一个结点,如果没有则为空 curr.next=prev; //prev是存储当前结点,为下一次循环做准备 prev=curr; //将当前结点变成下个结点,即将指向倒过来,当到链表的最后一个元素时,temp必定为null退出循环 curr=temp; } return prev; } }View Code
题目三:复杂链表的复制,同样借鉴LeetCode作者:jyd,这个是利用HashMap中键值对的映射关系来完成
public class Office35 { public static void main(String[] args) { Node head=null; //使用尾插法插入结点,时间复杂度有点高 for(int i=0;i<6;i++){ Node listNode=new Node(i); //判断头结点是否为空,是的话将一个节点对象赋给它,成为头节点 if(head==null){ head=listNode; }else { Node cur=head; //从头节点开始遍历链表,将新节点挂载到最后一个节点上 while (cur.next != null) { cur = cur.next; } cur.next=listNode; cur.next.random=cur; } } Solution02 solution02=new Solution02(); Node node=solution02.copyRandomList(head); while (node!=null){ //输出该结点的值和该结点指向结点的值 if(node.random!=null) { System.out.println("结点的值:"+node.val + " " + "结点的random指针"+node.random.val); } node=node.next; } } } class Node{ int val; Node next; //random是一个指向其他结点的指针 Node random; public Node(int val) { this.val = val; this.next = null; this.random = null; } } class Solution02 { //这个算法的复制原理就是利用hashmap的key和value的映射关系,完成复制 //先创建一个结点,将一个结点的val给它,然后利用hashmap创建映射关系 //再将链表的的指向给复制链表 public Node copyRandomList(Node head) { if(head==null){ return null; } Node cur=head; //利用hashmap的键值对的映射关系完成原链表与复制链表的映射关系 Map<Node,Node> map=new HashMap<>(); while (cur!=null){ //创建映射关系 map.put(cur,new Node((cur.val))); cur=cur.next; } //重新指向头结点 cur=head; while (cur!=null){ //将原链表的下一个结点指向赋值给赋值链表,map.get(key)是根据传入的key值取出相应的value值 map.get(cur).next=map.get(cur.next); //将原链表的random赋值给复制链表 map.get(cur).random=map.get(cur.random); cur=cur.next; } //返回复制链表的头结点 return map.get(head); } }View Code