刷题的网址是:CS-Notes/Leetcode 题解 - 链表.md at master · CyC2018/CS-Notes (github.com)
主要是按照上边这个网站上的题目进行刷题。先从数据结构进行刷题。
我是一个小白,所以先慢慢记录并总结刷题经验。
目前的刷题策略:
1.因为上边网站上推荐的有200道左右的题目,所以,每天先刷十道题目,并进行总结。
2.先看题目自己想思路,五分钟之内还不能解决的就看答案。
3.第一步先形成解题目的思路;第二步使用代码实现自己的思路。思考用什么变量、数据结构、第三步,看别人的代码,优化自己的代码,并记录不同之处。
4.每天的刷题时间是3个小时,后边轻车熟路了可以慢慢修改时间。
今天先从链表刷起来。
先回顾一下链表的基础知识。
1.链表(Linked List)介绍
链表是有序的列表,但是它在内存中是存储如下
1) 链表是以节点的方式来存储,是链式存储
2) 每个节点包含 data 域, next 域:指向下一个节点.
3) 如图:发现链表的各个节点不一定是连续存储.
4) 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定
1.1单链表(带头结点) 逻辑结构示意图如
一些链表功能代码演示:
1.2 双向链表应用实例
1.2.1管理单向链表的缺点分析:
1) 单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。
2) 单向链表不能自我删除,需要靠辅助节点 ,而双向链表,则可以自我删除,所以前面我们单链表删除 时节点,总是找到 temp,temp 是待删除节点的前一个节点(认真体会).
3) 分析了双向链表如何完成遍历,添加,修改和删
1.3 单向环形链表
约瑟夫问题
1.4 链表总结
1.链表分为三种:单向链表、双向链表、环形链表
2.链表作为一种数据结构,具有的特点:都有CRUD功能。
3.链表由节点组成,节点包含指针和数据,用代码实现的时候,需要知道链表是需创建节点类,至于增删改查的方法是需要在链表类中进行定义的。
开始刷题咯!!!
1. 找出两个链表的交点
160. Intersection of Two Linked Lists (Easy)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null){
return null;
}
ListNode pA = headA, pB = headB;
/**
我们首先保证pA和pB距离链表尾端距离相同,然后在开始向后边查找有没有相同的元素 */
//如果不是空链表,那么按照以下思路进行查找
while(pA != pB){
pA = pA == null? headB : pA.next;
pB = pB == null? headA : pB.next;
}
return pA;
}
}
这一道题目好浪漫。。。
竟然超出时间限制了。。。
/**
* 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) {
/**
1.需要用到辅助节点
2.双指针?
*/
if(head == null){
return null;
}
ListNode tempNode1 = head;
ListNode tempNode2 = head.next;
while(tempNode2 != null){
if(tempNode1 == head){
tempNode1.next = null;
}
tempNode2.next = tempNode1; //这个地方出现了逻辑错误。。。。
tempNode1 = tempNode2;
tempNode2 = tempNode2.next;
}
return tempNode1;
}
}
/**
* 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) {
/**
1.需要用到辅助节点
2.双指针?
*/
if(head == null){
return null;
}
ListNode tempNode1 = head;
ListNode tempNode2 = head.next;
while(tempNode2 != null){
ListNode tempNode3 = null;//引入新的变量可以存储下一个节点的位置
if(tempNode1 == head){
tempNode1.next = null;
}
tempNode3 = tempNode2.next;
tempNode2.next = tempNode1; //这个地方出现了逻辑错误。。。。
tempNode1 = tempNode2;
tempNode2 = tempNode3;
}
return tempNode1;
}
}
修改后的,成功了!!!
自己写的哪里错了。。。
那里改变了就要用新的变量进行存储,不然后边会出错。