每天一道算法题--单链表的相关操作
2017-09-14 01:20
387 查看
单链表在笔试面试中属于重点考察对象,这里总结几个常考的单链表操作。
删除单链表中的某一结点(不是从前一节点删除后一节点)
删除节点,此时这里给出的节点正是将删除节点,而且是单链表(注意尾节点的处理)
这里是是下一个节点的值直接付给要删除的节点,然后删除下一个节点即可
删除链表中值为val的节点
删除值为val的节点,一般遇到这种要注意头节点是否会改变年,如果改变需要将头节点先储存起来
删除链表中倒数第n个节点
因为在链表长度是不可知的,因此可以多创建一个指针来进行标记。即当一个指针只想被删除节点时,另外一个指针指向最后一个节点,期间相距n-1个节点。 但实际上这里设计的时候使两个指针相隔n个节点,以便通过前节点将后节点删除,而且注意这里可能会改变头节点,因此要保留头节点
在有序链表中删除重复的节点,但保留第一个重复的点
两个相邻的指针同时出发,当值不同时,都往前移动,当值相同时,则前指针不移动,后指针移动(腾讯有一道笔试题与此类似:找出红包金额出线数过半的金额数)
以上这道题有一道变形题,在有序链表中删除节点,但是所有重复节点都不保留,因此可能会改变头节点,因此需要对头节点进行数据备份
//构造链表结构 static class ListNode { int val; ListNode next; ListNode(int x) { val = x; } }
删除单链表中的某一结点(不是从前一节点删除后一节点)
删除节点,此时这里给出的节点正是将删除节点,而且是单链表(注意尾节点的处理)
这里是是下一个节点的值直接付给要删除的节点,然后删除下一个节点即可
public static void deleteNode(ListNode node) { if(node.next==null){ node=null; }else{ node.val=node.next.val; node.next=node.next.next; } }
删除链表中值为val的节点
删除值为val的节点,一般遇到这种要注意头节点是否会改变年,如果改变需要将头节点先储存起来
public static ListNode removeElements(ListNode head, int val) { if(head==null) return null; ListNode node=head; //先判断下一个节点是否为空 while(node.next!=null){ if(node.next.val==val){ node.next=node.next.next; }else{ //注意这里替换使用当前结点替换下一个节点 node=node.next; } } //把头节点放到最后一个判断 if(head.val==val){ head=head.next; } return head; }
删除链表中倒数第n个节点
因为在链表长度是不可知的,因此可以多创建一个指针来进行标记。即当一个指针只想被删除节点时,另外一个指针指向最后一个节点,期间相距n-1个节点。 但实际上这里设计的时候使两个指针相隔n个节点,以便通过前节点将后节点删除,而且注意这里可能会改变头节点,因此要保留头节点
public static ListNode removeNthFromEnd(ListNode head, int n) { if(head==null) return null; ListNode dummy = new ListNode(0); dummy.next = head; ListNode lastNode = dummy; ListNode headNode = dummy; for (int i = 1; i <= n + 1; i++) { lastNode = lastNode.next; } while (lastNode != null) { lastNode = lastNode.next; headNode = headNode.next; } headNode.next = headNode.next.next; return dummy.next; }
在有序链表中删除重复的节点,但保留第一个重复的点
两个相邻的指针同时出发,当值不同时,都往前移动,当值相同时,则前指针不移动,后指针移动(腾讯有一道笔试题与此类似:找出红包金额出线数过半的金额数)
public static ListNode deleteDuplicates(ListNode head) { if(head==null) return null; ListNode lastNode =head.next; ListNode headNode =head; while(lastNode!=null){ if(headNode.val==lastNode.val){ lastNode=lastNode.next; headNode.next=lastNode; }else{ headNode=headNode.next; lastNode=lastNode.next; } } return head; }
以上这道题有一道变形题,在有序链表中删除节点,但是所有重复节点都不保留,因此可能会改变头节点,因此需要对头节点进行数据备份
public static ListNode deleteDuplicates2(ListNode head) { if(head==null) return null; ListNode dummy = new ListNode(-1); dummy.next = head; ListNode lastNode =dummy.next; ListNode headNode =dummy; //全都是对下一个数据进行比较 while(lastNode.next!=null){ if(lastNode.next.val==headNode.next.val){ //比如链表如右:1,2,3,4,4,4,4,5,6,7,出现重复后,headNode停在第一个4的位置前面,下一个指针遍历到最后一个4的位置上 //在改变头节点时,尤其是已经有其他节点保存了头节点,需要借助指针的方式来改变,不可以改变内存地址的形式实现 //如果下一个节点还是值相等,则往后移一个节点 while(lastNode.next.val==headNode.next.val&&lastNode.next.next!=null&&lastNode.next.next.val==headNode.next.val){ lastNode=lastNode.next; } //这里要删除中间相同的n多个节点,此时headNode停在第一个4的位置前面(3),下一个指针遍历到最后一个4的位置上 //注意要把两个节点所在的节点一起删去 if(lastNode.next.next!=null){ headNode.next=lastNode.next.next; if(lastNode.next.next.next!=null){ lastNode.next=lastNode.next.next.next; }else{ lastNode.next=null; } }else{ lastNode.next=null; headNode.next=lastNode.next; } }else{ headNode=headNode.next; lastNod baa3 e=lastNode.next; } } return dummy.next; }
相关文章推荐
- 每天一道算法题(4)——O(1)时间内删除链表节点
- 每天一道算法题(8)——把二元查找树转变成排序的双向链表
- 每天一道算法题7 查找链表中倒数第k个结点 ; 输入一个单向链表。如果该链表的结点数为奇数,输出中间的结点;如果链表结点数为偶数,输出中间两个结点前面的一个
- 每天一道算法题(8)——把二元查找树转变成排序的双向链表
- 每天一道算法题7 查找链表中倒数第k个结点
- 单链表操作相关算法
- 每天一道算法题目(20)——复杂链表的拷贝
- 每天一道算法题目(20)——复杂链表的拷贝
- 每天一道算法题11 找出两个链表的第一个公共结点
- 链表的相关操作算法
- 每天一道算法题——合并两个排序的链表
- 每天一道算法题(16)——合并已排序的链表
- 校招准备系列:每天一道算法题(12)-从尾到头打印链表
- 校招准备系列:每天一道算法题(14)-合并两个排序的链表
- 每天一道算法题(16)——合并已排序的链表
- 每天一道算法题(16)——翻转链表
- 每天一道算法题——从尾到头输出链表
- 每天一道算法题(16)——翻转链表
- 每天一道算法题2 删除链表结点(时间复杂度为O(1)))
- 数据结构-单向链表相关操作算法