leetcode每日一题
今天的题目都比较简单,因此多刷几个
1:删除链表中的节点
题目链接:https://leetcode-cn.com/problems/delete-node-in-a-linked-list/
题目描述:
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为 要被删除的节点 。
例子:
输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
思路:直接将node节点的i爱一个节点的值赋值给node节点,然后将node的指向指到下下个节点即可。
代码:
// An highlighted block
//输入:head = [4,5,1,9], node = 5
//输出:[4,1,9]
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
2:移除链表中的元素
题目链接:https://leetcode-cn.com/problems/remove-linked-list-elements/
题目描述:
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
例子:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
思路:
因为头节点可能被删除,因此要定义一个节点,这个节点的next指针指向head,然后另外一个节点指向这个节点,开始遍历链表找到节点的值和给定的值相等的节点,改变指针指向
代码:
// An highlighted block
//输入:head = [1,2,6,3,4,5,6], val = 6
//输出:[1,2,3,4,5]
public ListNode removeElements(ListNode head, int val) {
ListNode dummy = new ListNode(-1);//定义一个呀节点,因为头节点也有可能被删除
dummy.next = head;
ListNode tempNode = dummy;
while (tempNode != null && tempNode.next != null) {
if (tempNode.next.val == val) {
tempNode.next = tempNode.next.next;
} else {
tempNode = tempNode.next;
}
}
return dummy.next;
}
3:删除链表的倒数第n的节点
题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
题目描述:
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
例子:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
思路:
首先统计链表元素的个数ans,然后遍历ans-n次,遍历之后将节点的next指向next的next。具体看代码吧。
代码:
//输入:head = [1,2,3,4,5], n = 2
//输出:[1,2,3,5]
//1,2 2
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode temp = head;
int ans = 0;//记录链表元素个数
//首先遍历链表,统计链表元素个数
while (temp != null) {
temp = temp.next;
ans++;
}
if (ans == 1) return null;//[1] 1这样的情况
ListNode dummy = new ListNode(-1);//需要定义一个呀节点,因为头节点可能会被删除
dummy.next = head;
ListNode tempNode = dummy;
//然后遍历链表ans-n次,修改指针指向
for (int i = 0; i < ans - n; i++) {
tempNode = tempNode.next;
}
tempNode.next = tempNode.next.next;
return dummy.next;
}
上面需要遍历两次链表,其实还可以进行优化
思路:
当链表总长度是k时,如果要删除倒数第n个节点(假设n小于k),那么首先要找到第k-n个节点,k-n这个节点就是要删除的节点的前一个节点。当找到k-n这个节点就好办了,直接将k-n的next指针指向下下一个节点即可。我们需要两个指针a和b。b指针先走n步,接着a和b指针同时往前走,当b指针走到链表末尾时,a指针就正好走到要删除的节点的前一个位置了,最后a节点的next指针指向下下一个节点,就可以完成删除操作了。
代码:
public ListNode removeNthFromEnd2(ListNode head, int n) {
//增加呀节点方便处理头节点
ListNode p = new ListNode(-1);
p.next = head;
ListNode a = p;
ListNode b = p;
//第一个循环,b指针先往前走n步
while (n > 0 && b != null) {
n--;
b = b.next;
}
//假设整个链表长度是5,n是10,那么第一次遍历完之后b就等于null
//于是后面的判断就不用做了,直接返回
if (b == null) {
return head;
}
//第二次,b指针走到最后,a指针也跟着走
//当遍历结束时,a指针就指向要删除的节点的前一个位置
while (b.next != null) {
a = a.next;
b = b.next;
}
//删除节点并返回
a.next = a.next.next;
return p.next;
}