您的位置:首页 > 职场人生

每天一道算法题--单链表的相关操作

2017-09-14 01:20 387 查看
单链表在笔试面试中属于重点考察对象,这里总结几个常考的单链表操作。

//构造链表结构
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单链表 算法 面试