链表的删除节点问题
由简入难捋一下
237&&面试题02.03
特殊条件有:
1.非末尾
2. 只给定被删节点,不能读到前节点。
3.只删一个。
4.不返回。
思路:将下一个节点的值复制过来,再删掉下一个节点。(神之脑筋急转弯)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;//复制值
node.next = node.next.next;//指向下下个节点
}
}
BTW C语言更简单。。。再加一个用于释放内存的指针(真·脑筋急转弯)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
void deleteNode(struct ListNode* node) {
struct ListNode* p = node->next;
*node = *(node->next);
free(p);
}
面试题18
Leetcode原题链接:18
特殊条件比较:
1.可能末尾、中间、头
2.从链表头开始,找到值匹配
3.只删一个
4.返回值
思路:
1.创一个空头节点,解决遍历头、删头。
2.设置指针遍历链表,条件是:下一节点不为空(否则直接找值会报错)且匹配给定值,如果下一节点为空,则循环到该接节点后退出循环即可。
3.直接出循环,删节点(所在节点直接指向下下个节点)
4.返回空节点下一个节点,即为新的头节点。
5.判断体外面不要不要不要忘了循环体(死循环报错超时)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteNode(ListNode head, int val) {
ListNode nhead = new ListNode(0);
nhead.next = head;
ListNode cur = nhead;
while(cur != null){
if(cur.next != null && cur.next.val == val){
cur.next = cur.next.next;
break;
}
cur = cur.next;
}
return nhead.next;
}
}
203
Leetcode原题链接:203
特殊条件比较:
1.可能末尾中间头------继续加个空头计算
2.从链表头开始,找到值匹配------继续循环cur.next
3.删所有符合条件的值------重点解决循环问题
4.返回值
思路:
与上题相同。在循环句前加else即可。目的:判断是否需要换下一指针:若未删则循环下一个;若删除则依旧循环该节点,因为next里面的节点发生了变化,要筛。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head == null) return head;
ListNode newhead = new ListNode(0);
newhead.next = head;
ListNode cur = newhead;
while(cur != null){
if(cur.next != null && cur.next.val == val){//如果next为空会报错,要确认next不为空
cur.next = cur.next.next;
}
else cur = cur.next;//如果不删则下一个节点,如果删除,则判断新的next节点是否符合
}
return newhead.next;
}
}