JAVA-数据结构-链表-附leetcode
1.简介
假设下面是个内存块 非连续内存空间存储数据
1 | ||
---|---|---|
2 | ||
3 |
yes——链表
结构:val next
| 元素 指针 | ----->|元素 指针 |----->|元素 指针| ----->null
单端链表
双端链表
时间复杂度
访问 | O(n) |
---|---|
搜索 | O(n) |
插入 | O(1) |
删除 | O(1) |
特点:读少写多,写很快,读很慢
2.JAVA链表基本操作
2.1 创建链表
//1.创建链表
LinkedList<Integer> list = new LinkedList<>();
2.2 添加元素
//2.添加元素 插入操作时间复杂度O(1)
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list.toString());
// 插入操作时间复杂度O(1) 但是由于你要先找到这个位置 所以总体时间复杂度O(n)
list.add(3,99);
System.out.println(list.toString());
2.3 访问元素O(1)
//3.访问元素 O(n)
int element = list.get(3);
System.out.println(element);
2.4 更新元素 O(1)
//4.更新元素 O(n)
list.set(2,88);
System.out.println(list.toString());
2.5 删除元素O(n)
//5.删除元素 O(n) 搜索到这个数O(n) 删除这个元素只有O(1)
list.remove(3);
System.out.println(list.toString());
2.6 链表长度
创建的时候,内部有一个count变量,所以 O(1)
//6. 长度 O(1) 里面有一个定义的变量
int length = list.size();
System.out.println(length);
2.7 链表搜索
//7.按值搜索元素 O(n)
int index = list.indexOf(99);
System.out.println(index);
3.Leetcode练习题
160 相交链表
题目思路,两个都从头同时开始走,走到头就从另外一个链表的开头开始走,
如果两个相交,那么最后一部分路是一样的,走同样的路必然相遇,
所以如果相遇就将后面的部分都返回
没相遇到底 两轮还是null 返回null
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//如果两个链表有一个为空,那必然不想交,直接返回null
if (headA == null || headB == null) return null;
//定义两个链表的起点
ListNode pA = headA, pB = headB;
//如果两个值不相等,就遍历下去
while (pA != pB) {
//pA 遍历到最后一个,就从b的开始从头遍历
//注意是headB
pA = pA == null ? headB : pA.next;
//pB 遍历到最后一个,就从a的开始从头遍历
//注意是headA
pB = pB == null ? headA : pB.next;
}
//返回pA pB都行 如果到底就是null 如果没到底就是相交部分
return pA;
}
203移除链表元素
思路:
首先设置一个节点标记接下来整个链表
然后节点往后遍历,遇到对应值直接改指针跳过该值
public ListNode remoElements(ListNode head, int val){
//设置一个节点指向该链表,
ListNode headhead = new ListNode(0);
headhead.next = head;
//设置一个节点用来遍历
ListNode cur = headhead;
//当cur指向节点不为null就遍历
while(cur.next != null){
//如果cur指向的节点值为对应值,则直接将节点指向下一个跳过该节点
if(cur.next.val = val){
cur.next = cur.next.next;
}else{
//否则就正常遍历
cur = cur.next;
}
}
return headhead.next;
}
206 反转链表
思路:设置一个空的头结点,一组一组反转,三个依次赋值
public ListNode reverseList(ListNode head){
if(head == null || head.next == null) return head;
ListNode pre = null;
ListNode cur = head;
ListNode next = head.next;
while(next != null){
//当前节点指针,指向前一个节点
cur.next = pre;
//前一个节点的值换为当前节点
pre = cur;
//当前节点换为下一个节点的值,也就是说完成了下一个节点指向原先当前节点
cur = next;
//下一个节点换为下下个节点开始新一轮循环
next = next.next;
}
//循环结束,将最后指向的节点反过来
cur.next = pre;
return cur;
}