算法基础-链表

算法基础-链表

线性表,顺序表,链表

  • 链表是线性表的一种。线性表是最基本、最简单、也是最常用的一种数据结构。
  • 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表有两种存储方式,一种是顺序存储结构,另一种是链式存储结构。我们常用的数组就是一种典型的顺序存储结构。
  • 链式存储结构就是两个相邻的元素在内存中可能不是相邻的,每一个元素都有一个指针域,指针域一般是存储着到下一个元素的指针。这种存储方式的优点是插入和删除的空间复杂度为 O(1),不会浪费太多内存,添加元素的时候才会申请内存,删除元素会释放内存。缺点是访问的时间复杂度最坏为 O(n)。
  • 顺序表的特性是随机读取,也就是访问一个元素的时间复杂度是O(1),链式表的特性是插入和删除的时间复杂度为O(1)。
  • 链表就是链式存储的线性表。根据指针域的不同,链表分为单向链表、双向链表、循环链表等等。

Java链表的基本操作

  • 反转链表
    • 单向链表
    • 双向链表
  • 删除节点
  • 快慢指针

Remove Duplicates from Sorted List

Question

Solution

  • 思路: 遍历之,遇到当前节点与下一节点值相同,则删除
[code lang=java] public ListNode deleteDuplicates(ListNode head) { if(head==null) return null; ListNode node=head; while(node.next!=null){ if(node.next.val==node.val){ node.next=node.next.next; }else{ node=node.next; } } return head; } [/code]
  • 复杂度分析: 遍历一次,时间复杂度O(n);使用一个中间变量,空间复杂度O(1)

Remove Duplicates from Sorted List II

Question

Solution

  • 思路: 考虑到链表头不确定(可能被删除,也可能保留),这里引入dummy node(虚拟节点,head的前向指针)
[code lang=java] public ListNode deleteDuplicates(ListNode head) { if(head==null) return null; ListNode dummy=new ListNode(0); dummy.next=head; ListNode node=dummy; while(node.next!=null&&node.next.next!=null){ if(node.next.next.val==node.next.val){ int temp=node.next.val; while(node.next!=null&&node.next.val==temp){ node.next=node.next.next; } }else{ node=node.next; } } return dummy.next; } [/code]
  • 复杂度分析: 时间复杂度为O(2n),空间复杂度近似O(1).

Remove Linked List Elements

Question

Solution

  • 思路: 删除指定节点,头节点可能被干掉,引入dummy node
[code lang=java] public ListNode removeElements(ListNode head, int val) { if(head==null) return null; ListNode dummy=new ListNode(0); dummy.next=head; ListNode node=dummy; while(node.next!=null){ if(node.next.val==val){ node.next=node.next.next; }else{ node=node.next; } } return dummy.next; } [/code]

Partition List

Question

  • leetcode
  • lintcode
  • Problem Statement: 划分链表,使得所有小于x的节点排在大于等于x的节点之前,保留原有顺序
  • Difficulty:Medium. 需二刷.

Solution

  • 思路:使用两路指针,遍历链表,小于x的跟左指针,大于等于的跟右指针;
[code lang=java] /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode partition(ListNode head, int x) { ListNode left=new ListNode(-1); ListNode right=new ListNode(-1); ListNode leftOrigin=left; ListNode rightOrigin=right; ListNode node=head; while(node!=null){ if(node.val<x){ left.next=node; left=node; }else{ right.next=node; right=node; } node=node.next; } right.next=null; left.next=rightOrigin.next; return leftOrigin.next; } } [/code]
  • 复杂度: 遍历一次,时间复杂度O(n),空间O(1)

转载于:https://my.oschina.net/husthang/blog/840605

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值