链表基础训练(一)
作者:互联网
题目一:
删除链表中的重复元素。
思路:一是利用哈希表(HashSet),哈希表特别适合于判断集合中是否有重复的元素。二是直接使用遍历链表,使用两层for循环去遍历再来找出重复的元素。下面给出第一种方法的代码。
1 import java.util.HashSet; 2 3 public class 删除重复结点 { 4 // 创建链表的节点 5 private static class ListNode { 6 ListNode next; 7 Object value; 8 9 public ListNode(Object value){ 10 super(); 11 this.value = value; 12 } 13 } 14 15 public static void main(String[] args){ 16 int data[] = {1, 6, 6, 7, 3, 3, 5, 3, 8, 9, 10, 10}; // 输出 1 6 7 3 5 8 9 10 17 //哑元 空节点 18 ListNode head = new ListNode(null); 19 ListNode p = head; 20 for(int i = 0; i < data.length; i++){ 21 p.next = new ListNode(data[i]); 22 //指针往下进行移动 23 p = p.next; 24 } 25 removeReptition(head); 26 ListNode p1 = head.next; 27 while(p1 != null){ 28 System.out.print(p1.value + " "); 29 p1 = p1.next; 30 } 31 } 32 33 private static void removeReptition(ListNode head){ 34 ListNode p = head.next; 35 ListNode pre = head; 36 HashSet set = new HashSet(); 37 //遍历哈希表 38 while(p != null){ 39 if(set.contains(p.value)){ 40 pre.next = p.next; 41 }else{ 42 set.add(p.value); 43 pre = p; 44 } 45 p = p.next; 46 } 47 } 48 }View Code
题目二:
实现一个算法,输出单向链表中的第k个节点。
思路: 从题目可以看出,只是给出了链表的头结点,所以我们是不知道链表中含有几个元素,假如知道几个元素的话那就很简单了。由于我们这里只知道头节点,我们可以使用一种叫快行指针(双行指针)的技巧来解决这道题目。
1 public class 倒数第k个节点 { 2 // 特别要注意边界的问题 3 public static ListNode FindKthToTail(ListNode head, int k) { 4 if (head == null || k <= 0) 5 return null; 6 ListNode p1 = head; 7 ListNode p2 = head; 8 int count = 0; 9 while (p2 != null && count < k) { 10 p2 = p2.next; 11 count++; 12 } // p2 与 p1 相差 k 距离 13 if (count < k) { 14 return null; 15 } 16 while (p2 != null) { // 当p2为null时,p1就指向了要删除的那个节点。 17 p1 = p1.next; 18 p2 = p2.next; 19 } 20 // System.out.println(p1.data); 21 return p1; 22 } 23 24 public static void main(String[] args) { 25 int[] arr = { 1, 2, 3, 4, 5 }; 26 ListNode head = new ListNode(arr[0]);// 哑元 27 ListNode p = head; 28 for (int i = 1; i < arr.length; i++) { 29 p.next = new ListNode(arr[i]); 30 p = p.next; 31 } 32 // System.out.println(head); 33 ListNode l1 = FindKthToTail(head, 3); 34 System.out.println("倒数第三个节点:" + l1.val); 35 36 } 37 // 5,{1,2,3,4,5} 38 } 39 class ListNode { 40 int val; 41 ListNode next = null; 42 43 ListNode(int val) { 44 this.val = val; 45 } 46 47 @Override 48 public String toString() { 49 StringBuilder sb = new StringBuilder(val + ""); 50 ListNode nnext = next; 51 while (nnext != null) { 52 sb.append(nnext.val); 53 nnext = nnext.next; 54 } 55 return sb.toString(); 56 } 57 }View Code
结果:
题目三:
实现一个算法,删除单向链表中的某个节点,假定你只能访问该节点。输入单向链表a->b->c->d->e中的c,结果不返回任何数据,单链表变为a->b->d->e。给定待删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true。
思路:题目中限定了只能访问该节点,那么之前的节点我们是不能够访问到的,所以只能访问到节点以及通过next来访问下面的节点。我们可以使用到一种特别的技巧就是复制当前节点的后继节点的内容给当前节点,然后改变当前节点的指向跳过后继直接指向后继的下一个元素。当传入的节点是最后一个节点的时候我们是不能够进行删除的,因为最后一个节点的next为空我们不能够复制内容来进行删除的,所以直接返回false。
1 public class 删除某节点 { 2 public static boolean removeNode(ListNode pNode) { 3 if (pNode.next == null) 4 return false; 5 pNode.val = pNode.next.val;// 复制后继的内容 6 pNode.next = pNode.next.next;// 跨越后继 7 return true; 8 } 9 public static void main(String[] args) { 10 int[] arr = { 1, 2, 3, 4, 5 }; 11 ListNode head = new ListNode(arr[0]);// 哑元 12 ListNode p = head; 13 for (int i = 1; i < arr.length; i++) { 14 p.next = new ListNode(arr[i]); 15 p = p.next; 16 } 17 ListNode p1 = head.next; 18 removeNode(p1); 19 while(head!=null){ 20 System.out.println(head.val); 21 head = head.next; 22 } 23 } 24 } 25 class ListNode { 26 int val; 27 ListNode next = null; 28 29 ListNode(int val) { 30 this.val = val; 31 } 32 33 @Override 34 public String toString() { 35 StringBuilder sb = new StringBuilder(val + ""); 36 ListNode nnext = next; 37 while (nnext != null) { 38 sb.append(nnext.val); 39 nnext = nnext.next; 40 } 41 return sb.toString(); 42 } 43 }View Code
结果:
标签:head,ListNode,next,链表,public,基础训练,节点 来源: https://www.cnblogs.com/xiaoyh/p/10386288.html