数组
查找
内存连续的存储空间,内存管理器可以实现访问任何一个位置的元素,O(1)的查找。
插入
[1,2,3,4,5] 在3和4之间插入一个值,6,需要把4,5 往后挪动。平均时间复杂度是O(N),删除也是O(n) 的平均时间复杂度。
链表
我想改变他的插入和更新的时间复杂度,有没有好的数据结构呢?
链表 – linked List
本质上,有一个指针,链向下一个节点,整个连成一个表
链表的常用操作:
插入和删除
插入:把上一个节点的指针指向当前,当前节点的指针指向下一个。
删除:修改前后两个指针的指向
查询 O(n) , 但是在插入和删除之前,需要查找到对应的节点前插入或者删除。
插入和删除O(1)
链表和数组的题
1、反转链表,出镜率数一数二
1-2-3-4-5
反转
5-4-3-2-1
主要考察代码能力:
递归方法解题思路
递归思路:
1、定义终止条件,(当遍历到最后一个节点的时候,方法返回,开始出栈)
2、出栈操作
2.1 将最后一个节点的next指针指向前一个节点
2.2 注意,将前一个节点的指针记录置空
2.3 注意,边界条件的处理,当输入是空的时候,输出也应该是空,处理好就行
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null ) {
return head;
}
ListNode next = head.next;
final ListNode listNode = reverseList(next);
next.next = head;
head.next = null;
return listNode;
}
}
循环法解题思路
定义两个变量:
1、currNode 代表,当前遍历到的值
2、newLinkListLastNode :代表反转后的尾节点
将prev.next = newLinkListLastNode;
更新尾节点 newLinkListLastNode = currNode;
往后遍历
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public static ListNode reverseList(ListNode head) {
ListNode currNode = head;
ListNode newLinkListLastNode = null;
while (currNode != null) {
ListNode next = currNode.next;
currNode.next = newLinkListLastNode;
newLinkListLastNode = currNode;
currNode = next;
}
return newLinkListLastNode;
}
}