题解均为java
leetcode第203题:移除链表元素
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
这个题主要的一个问题是如果头结点的值是给定值的话,怎么处理?
因此,要引入一个虚拟的头结点,去保存这个链表的信息,然后再return的时候,把这个虚拟头结点去掉,java有自动垃圾回收,不用像c++一样,我们要去释放掉删除节点的内存,嘻嘻
我这里面复制了一个list数组,然后在这里面修改的,而原本给的head数组,完全没有修改,一直从头遍历到尾
/**
* 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) {
ListNode tmp = new ListNode(0);
ListNode head2 = new ListNode(0);
tmp.next = head2 ;
head2.next = head;
while (head!=null){
if (head.val==val){
head2.next=head.next;
}else{
head2=head2.next;
}
head=head.next;
}
return tmp.next.next;
}
}
leetcode第707题:设计链表
憨憨题,调试贼不好调,而且有些new起来不太习惯,毕竟现在双向链表直接就是LInkedList了。
主要记住记得size的修改;
public class ListNode {
int val;
ListNode next;
ListNode prev;
ListNode(int x) {
val = x; }
}
class MyLinkedList {
int size;
ListNode head,tail;
/** Initialize your data structure here. */
public MyLinkedList() {
size=0;
head = new ListNode(0);
tail = new ListNode(0);
head.next= tail;
tail.prev =head;
}
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
public int get(int index) {
if (index<0||index>=size){
return -1;
}
ListNode curr=head;
if (index+1<size-index){
for(int i = 0; i < index + 1; ++i) curr = curr.next;
}else{
curr = tail;
for (int i=0;i<size-index;i++){
curr=curr.prev;
}
}
return curr.val;
}
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
public void addAtHead(int val) {
ListNode tmp = new ListNode(val);
ListNode pree = head,curr = head.next;
pree.next = tmp;
curr.prev = tmp;
tmp.prev=pree;
tmp.next = curr;
size++;
}
/** Append a node of value val to the last element of the linked list. */
public void addAtTail(int val) {
ListNode tmp = new ListNode(val);
ListNode pree = tail.prev,curr = tail;
pree.next = tmp;
curr.prev=tmp;
tmp.prev =pree;
tmp.next=curr;
size++;
}
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
public void addAtIndex(int index, int val) {
// If index is greater than the length,
// the node will not be inserted.
if (index > size) return;
// [so weird] If index is negative,
// the node will be inserted at the head of the list.
if (index < 0) index = 0;
// find predecessor and successor of the node to be added
ListNode pred, succ;
if (index < size - index) {
pred = head;
for(int i = 0; i < index; ++i) pred = pred.next;
succ = pred.next;
}
else {
succ = tail;
for (int i = 0; i < size - index; ++i) succ = succ.prev;
pred = succ.prev;
}
// insertion itself
++size;
ListNode toAdd = new ListNode(val);
toAdd.prev = pred;
toAdd.next = succ;
pred.next = toAdd;
succ.prev = toAdd;
}
/** Delete the index-th node in the linked list, if the index is valid. */
public void deleteAtIndex(int index) {
if (index<0||index>=size) return;
ListNode pree,curr;
if (index+1<size-index){
pree = head;
for(int i = 0; i < index ; i++) pree = pree.next;
curr = pree.next.next;
}else{
curr = tail;
for (int i=0;i<size-index-1;i++){
curr=curr.prev;
}
pree = curr.prev.prev;
}
pree.next =curr;
curr.prev = pree;
size--;
}
}
leetcode第206题:反转链表
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
思路:指定一个新的NULL节点,然后对链表进行循环,依次将指针反转,最后返回尾结点指针
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while(curr!=null){
ListNode nextNode = curr.next;
curr.next = prev;
prev = curr;
curr = nextNode;
}
return prev;
}
}
leetcode第142题.环形链表II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
进阶:
你是否可以使用 O(1) 空间解决此题?
这个题有点像是脑筋急转弯,知道答案的很快就能写出来,不知道答案的想半天也想不出来,可能这就是刷题的意义吧(笑),本算法要达成进阶目标
**思路:可以使用快慢指针法, 分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
那么,设head节点到环入口节点中间(不包括入口节点)有x个节点,环入口节点到fast和slow相遇的节点之间有y个节点,fast和slow相遇的节点到环入口节点之间有z个节点(注意跟上一个不一样),那么fast就走过了x+n(y+z)+y slow就走过了x+y,slow走了x+y步,那么fast走了2(x+y)步,x+y=n(y+z) .
这个公式说明什么呢?
若n为1的时候,公式就化解为 x = z,
这就意味着,「从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点」。
也就是在相遇节点处,定义一个指针index1,在头结点处定一个指针index2。
让index1和index2同时移动,每次移动一个节点, 那么他们相遇的地方就是 环形入口的节点。
那么 n如果大于1是什么情况呢,就是fast指针在环形转n圈之后才遇到 slow指针。
其实这种情况和n为1的时候 效果是一样的,一样可以通过这个方法找到 环形的入口节点,只不过,index1 指针在环里 多转了(n-1)圈,然后再遇到index2,相遇点依然是环形的入口节点。
**
更加详细的图文解释详见这位大佬的:https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(true){
if (fast == null|| fast.next==null){
return null;}
else if (fast==slow){
break;
}
else {
fast = fast.next.next;
slow = slow.next;
}
}
fast = head;
while(true){
if (fast==slow) return slow;
else {
fast = fast.next;
slow = slow.next;
}
}
}
}