今天是链表的学习,对于链表的接触还是大一上学期学c语言的时候接触得比较多,学期结束的课设基本上都需要熟练掌握链表才能做出来所以我对链表还算比较熟悉。但后面学java我就更倾向于使用ArrayList,太久没用链表了今天做题差点给我绕晕了。
203.移除链表元素
对链表的增删是链表的基本操作了,相对简单需要注意的是链表头和和链表尾这两个地方是比较容易忽略和做错的地方。
具体代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
while(head!=null&&head.val==val)
head=head.next;
ListNode p=head;
ListNode q=head;
while(p!=null){
if(p.val==val){
q.next=p.next;
}
else
q=p;
p=p.next;
}
return head;
}
}
707.设计链表
说实话这道题看得我有点头晕了,我当时学c的时候还没做过这种题,所以这对我也算学新东西了,主要是我感觉题目描述得有点模糊了我没太懂题目的意思(也可能是我自己理解能力不够) 而且今天有点忙就直接把解题步骤看了(没太理解)直接把源码照搬了。
具体代码:
class ListNode {
int val;
ListNode next;
ListNode(){}
ListNode(int val) {
this.val=val;
}
}
class MyLinkedList {
//size存储链表元素的个数
int size;
//虚拟头结点
ListNode head;
//初始化链表
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
//获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点
public int get(int index) {
//如果index非法,返回-1
if (index < 0 || index >= size) {
return -1;
}
ListNode currentNode = head;
//包含一个虚拟头节点,所以查找第 index+1 个节点
for (int i = 0; i <= index; i++) {
currentNode = currentNode.next;
}
return currentNode.val;
}
//在链表最前面插入一个节点,等价于在第0个元素前添加
public void addAtHead(int val) {
addAtIndex(0, val);
}
//在链表的最后插入一个节点,等价于在(末尾+1)个元素前添加
public void addAtTail(int val) {
addAtIndex(size, val);
}
// 在第 index 个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
// 如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点
// 如果 index 大于链表的长度,则返回空
public void addAtIndex(int index, int val) {
if (index > size) {
return;
}
if (index < 0) {
index = 0;
}
size++;
//找到要插入节点的前驱
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
ListNode toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
}
//删除第index个节点
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
if (index == 0) {
head = head.next;
return;
}
ListNode pred = head;
for (int i = 0; i < index ; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
206.反转代码
看完题目我马上想到的就是需要用到两个循环,一想到两个循环我就想用双指针来做,然后看了文章果然是有双指针的做法的,看完思路后我发现自己是越发是喜欢双指针了,希望自己能越来越熟的使用双指针。
具体代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode p=head;
ListNode q=null;
ListNode s=null;
while(p!=null){
q=p;
p=p.next;
q.next=s;
s=q;
}
return s;
}
}
记录
已经连续打卡3天了,我发现了自己的一个问题,我写都博客基本不怎么讲解做题思路更多的是我自己的做题感受主要是我也是初学者,其次我写博客的目的也是希望能这样每天激励自己,比起给别人看我的博客更偏向于是给自己看的,等我学有所成应该也会开始写一些讲解类的博客吧,感觉写博客还挺有意思的。
day3!!!