链表

剑指offer 56.删除有序链表中的重复结点

橙三吉。 提交于 2020-02-22 21:25:08
56. 删除有序链表中的重复结点 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 分析 借助辅助头结点,可避免单独讨论头结点的情况。设置两个结点 pre 和 cur,当 cur 和 cur.next 值相等,cur 一直向前走,直到不等退出循环,这时候 cur 指的值还是重复值,调整 cur 和 pre 的指针再次判断 /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ 1 public class Solution { 2 public ListNode deleteDuplication(ListNode pHead) 3 { 4 if(pHead == null || pHead.next == null){ 5 return pHead; 6 } 7 8 // 每访问一个结点,循环判断是否重复 9 ListNode cur = pHead; // 指向当前结点 10 // 创建一个辅助头结点,指向前一个元素的指针,方便删除 11 ListNode head = new ListNode

【集合框架】JDK1.8源码分析之LinkedHashMap(二)

这一生的挚爱 提交于 2020-02-22 20:51:30
一、前言   前面我们已经分析了HashMap的源码,已经知道了HashMap可以用在哪种场合,如果这样一种情形,我们需要按照元素插入的顺序来访问元素,此时,LinkedHashMap就派上用场了,它保存着元素插入的顺序,并且可以按照我们插入的顺序进行访问。 二、LinkedHashMap用法 import java.util.Map; import java.util.LinkedHashMap; public class Test { public static void main(String[] args) { Map<String, String> maps = new LinkedHashMap<String, String>(); maps.put("aa", "aa"); maps.put("bb", "bb"); maps.put("cc", "cc"); for (Map.Entry entry : maps.entrySet()) { System.out.println(entry.getKey() + " : " + entry.getValue()); } } } View Code 说明:以上是展示LInkedHashMap简单用法的一个示例,可以看到它确实按照元素插入的顺序进行访问,保持了元素的插入顺序。更具体的用户可以去参照API。 三

234. 回文链表

送分小仙女□ 提交于 2020-02-22 18:56:27
判断一个链表是否为回文链表。 该题目来自力扣题库 示例 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 思路 使用栈结构,把当前链表全部压入堆栈。之后再按顺序比较链表节点以及出栈节点是否相同 代码 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public boolean isPalindrome ( ListNode head ) { if ( head == null || head . next == null ) { return true ; } Stack < ListNode > stack = new Stack < ListNode > ( ) ; ListNode cur = head ; while ( cur != null ) { stack . push ( cur ) ; cur = cur . next ; } cur = head ; while ( stack . size ( ) > 0 ) { ListNode prev =

小白算法积累——单链表25#带头结点单链表+穿插+逆置

被刻印的时光 ゝ 提交于 2020-02-22 16:07:52
题目 :设线性表L=(a1,a2,a3,…an-2,an-1,an)采用带头结点的单链表保存,链表中的结点定义如下: typedef struct node { int data; struct node*next }Node; 请设计一个 空间复杂度为O(1)且时间上尽可能高效 的算法,重新排列L中的各结点,得到线性表L’=(a1,an,a2,an-1,a3,an-2…) 关键字 :带头结点单链表+穿插+逆置 思路 :为了达到穿插+逆置的效果,我们选择 分段 + 逆置+插入 先观察L=(a1,a2,a3,…an-2,an-1,an)和L’=(a1,an,a2,an-1,a3,an-2,…) 发现L’是由L摘取第一个元素,再摘取倒数第一个元素…依次合并而成的。 为了方便链表后半段取元素,需要先将L后半段原地逆置【题目要求空间复杂度为O1,不能借助栈】,否则每取最后一个结点都需要遍历一次链表。 1)先找出链表L的中间结点,利用 速度差产生路程差法 ps:顺序表就是“直接算算地址”法了 为此设置两个指针p和q,指针p每次走一步,指针q每次走两步 当指针q到达链尾时,指针p自然就在链表的中间结点 2)将L的后半段结点原地逆置 需要变量:q的后继结点指针r,负责将“逆置指针”的工作 3)从单链表前后两段中依次各取一个结点,按要求重排。 需要变量: void change_list (

go语言实现单链表

吃可爱长大的小学妹 提交于 2020-02-22 15:27:04
线性表 包含两种存储方法:顺序存储结构和链式存储结构,其中顺序表的缺点是不便插入与删除数据。 单链表 :每个结点包含两部分:数据域+指针域,上一个结点的指针指向下一结点,依次相连,形成链表。特别注意的是每个链表必须包含 头结点 (数据域一般无意义或者为空,有时用来存储链表长度等等) 下面的代码实现链表的 基本操作 和 辅助操作 ,基本操作指的是插入数据、删除数据、查找数据、求链表长度;而辅助操作指的是创建结点、创建(初始化 )链表、判断是否为空链表。和其他语言不同之处是 Go语言具有垃圾自动回收的特性 ,因此不需要释放指针或内存,后续没有用到的变量Go语言会自动回收。 // 单链表: package main import "fmt" // 创建节点结构/类型 type Node struct { Data interface{} Next *Node } // 创建链表结构 type LList struct { Head *Node Length int // 这里的链表长度不计入头节点 } // a.设计接口: type Method interface { Insert(i int, v interface{}) // 增 Delete(i int) // 删 GetLength() int // 获取长度 Search(v interface{}) int // 查

Java ---- 链表逆序

自古美人都是妖i 提交于 2020-02-22 15:02:56
public class LinkedListRevert { public static void main(String[] args) { Node next3 = new Node(4,null); Node next2 = new Node(3,next3); Node next = new Node(2,next2); Node head =new Node(1,next); Node tmp = head; // 保存首节点 while (head!=null){ System.out.println(head.value); head=head.next; } Node revertHead = revert(tmp); while (revertHead!=null){ System.out.println(revertHead.value); revertHead=revertHead.next; } } public static Node revert(Node head){ Node prev = null; Node next = head.next; while(head!=null){ next = head.next; head.next = prev; prev = head; head = next; } return prev; } }

Reverse Linked List II 单向链表逆序(部分逆序)

荒凉一梦 提交于 2020-02-22 15:02:28
0 问题描述 原题点击这里。 将单向链表第 m 个位置到第 n 个位置倒序连接。例如, 原链表: 1-> 2->3->4 ->5, m=2, n =4 新链表: 1-> 4->3->2 ->1 (注:最终的新链表记为 head ,过程中临时使用的一个链表头记为 h ) 1 基本思路 首先考虑整个链表的情况。见到单向链表的第一反应自然是轮询链表 head 中每个节点,轮询过程中按需要建立一个新链表 h ,每次访问一个节点,就将这个节点放在前一个访问的节点之后,这样便实现了倒序。 然后再考虑部分倒序。要部分倒序,便要找出这部分从哪里开始,从哪里结束,根据前面的方法将该部分倒序之后,将倒序后的部分链表链上其他部分。 2 单向链表逆序 假设有三个节点,其过程如图( 1 )所示。 第一步取出 node1 ,新链头指向 node1 , node1->next 指向空,其他部分不变; 第二步取出 node2 ,新链头指向 node2 , node2->next 指向前一个访问的节点(即 node1 ) ; 第二步取出 node3 ,新链头指向 node3 , node3->next 指向前一个访问的节点(即 node2 ) ; 从这个过程中可以看到几点: 这是一个循环过程。循环的次数 = 链表中节点的个数。 每个节点都访问了且只访问一次,因而时间复杂度是 O(n) 。 需要三个辅助变量。 1

leetcode解题之回文链表

爷,独闯天下 提交于 2020-02-22 12:14:29
请判断一个链表是否为回文链表。 示例 1 : 输入 : 1 - > 2 输出 : false 示例 2 : 输入 : 1 - > 2 - > 2 - > 1 输出 : true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/palindrome-linked-list 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 先写一个简单的迭代法对比法(使用额外空间) /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public boolean isPalindrome ( ListNode head ) { ListNode temNode = head ; String s1 = "" , s2 = "" ; while ( temNode != null ) { s1 += temNode . val ; s2 = temNode . val + s2 ; temNode =

ConcurrentHashMap源码分析

隐身守侯 提交于 2020-02-22 11:48:17
ConcurrentHashMap解决了HashMap的线程不安全问题,在分析之前先介绍一个将HashMap线程安全的方法。利用 Collections.synchronizedMAp方法 调用内部类 SynchronizedMap HashMap<String, String> map = new HashMap<>(); Map m = Collections.synchronizedMap(map); private static class SynchronizedMap<K,V> implements Map<K,V>, Serializable { private static final long serialVersionUID = 1978198479659022715L; private final Map<K,V> m; // Backing Map final Object mutex; // Object on which to synchronize SynchronizedMap(Map<K,V> m) { this.m = Objects.requireNonNull(m); mutex = this; } SynchronizedMap(Map<K,V> m, Object mutex) { this.m = m; this.mutex =

22_链表中倒数第k个结点

空扰寡人 提交于 2020-02-22 05:47:17
链表中倒数第k个结点 输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。 示例: 给定一个链表: 1->2->3->4->5, 和 k = 2. 返回链表 4->5. 解法: 用两个指针,让前指针往前走k步后,后指针和前指针同时往前走,直到前指针为空时停下。 遇到的问题: 在解决链表长度小于K时,将判定结束的条件写到了while中,导致secod指针还没有指向头结点。如上面找倒数第三个。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* getKthFromEnd(ListNode* head, int k) { if(head == nullptr || k < 0) return nullptr; ListNode* first = nullptr; ListNode* second = nullptr