链表

刷题No28. copy-list-with-random-pointer(深拷贝一个链表)(java)【链表】

不打扰是莪最后的温柔 提交于 2020-02-13 03:19:32
题目: 现在有一个这样的链表:链表的每一个节点都附加了一个随机指针,随机指针可能指向链表中的任意一个节点或者指向空。 请对这个链表进行深拷贝。 思路: 先将原节点进行复制 再将原节点的random指针进行复制 从链表中将复制的节点拆分出来 代码: package com.company; public class TestNo28 { static class RandomListNode{ int val; RandomListNode next,random; RandomListNode(int x){ this.val = x; } public String toString(){ if(this.next == null){ return String.valueOf(this.val); } return this.val + "->" + this.next.toString(); } } public static void main(String[] args) { TestNo28 t = new TestNo28(); RandomListNode head = new RandomListNode(0); head.next = new RandomListNode(2); head.next.next = new RandomListNode(5);

Leetcode初学——旋转链表

左心房为你撑大大i 提交于 2020-02-13 03:16:44
题目: 分析: 以1->2->3->4->5 k=2为例 将链表首尾相连 将head和end依次向后移n-k个位置 n为原链表长度 在这里需要移3个位置 再将end 的next改为null 这道题就算完成了 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode rotateRight(ListNode head, int k) { ListNode end=head; //当链表为空时,直接返回 if(head==null) return head; int n=1; while(end.next!=null){ n++; end=end.next; } k=k%n; //当k的余数为0时,链表不需要移动,直接返回head if(k==0)return head; end.next=head; for(int i=0;i<n-k;i++){ head=head.next; end=end.next; } end.next=null; return head; } } 结果: 来源: CSDN 作者: 艾姆鸥

反转链表

半腔热情 提交于 2020-02-13 02:06:33
问题: 分别用递归和非递归方式来实现反转链表。 思路1: 递归。 java代码: ListNode reverseList ( ListNode head , ListNode newHead ) { if ( head == null || head . next == null ) { newHead = head ; return head ; } ListNode pre = reverseList ( head . next , newHead ) ; pre . next = head ; head . next = null ; return head ; } 思路2: 非递归。 java代码: ListNode reverseList ( ListNode head ) { ListNode dummy = new ListNode ( 0 ) ; dummy . next = head ; if ( head == null ) return head ; ListNode curr = head . next ; head . next = null ; while ( curr != null ) { ListNode next = curr . next ; curr . next = dummy . next ; dummy . next = curr ;

7-4 重排链表 (25分)

独自空忆成欢 提交于 2020-02-13 01:53:25
给定一个单链表 L ​ 1 ​​ →L ​ 2 ​​ →⋯→L ​n− 1 ​​ →L ​n ​​ ,请编写程序将链表重新排列为 L ​n ​​ →L ​ 1 ​​ →L ​n− 1 ​​ →L ​ 2 ​​ →⋯。例如:给定L为 1 → 2 → 3 → 4 → 5 → 6 ,则输出应该为 6 → 1 → 5 → 2 → 4 → 3 。 输入格式: 每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址和结点总个数,即正整数N ( ≤ 10 ​ 5 ​​ ) 。结点的地址是 5 位非负整数, NULL 地址用− 1 表示。 接下来有N行,每行格式为: Address Data Next 其中Address是结点地址;Data是该结点保存的数据,为不超过 10 ​ 5 ​​ 的正整数;Next是下一结点的地址。题目保证给出的链表上至少有两个结点。 输出格式: 对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。 输入样例: 00100 6 00000 4 99999 00100 1 12309 68237 6 - 1 33218 3 00000 99999 5 68237 12309 2 33218 输出样例: 68237 6 00100 00100 1 99999 99999 5 12309 12309 2 00000 00000 4

什么是队列?

萝らか妹 提交于 2020-02-13 01:46:00
与前面提到的 数据结构 相同,队列中的数据也呈 线性排列 。虽然与 栈 有些相似,但队列中添加和删除数据的操作分别是在 两端 进行的,就和队列这个名字一样,把它想象成排成一队的人更容易理解。在队列中,处理总是从第一名开始往后进行,而新来的人只能排在队尾。 队列是什么? 如上就是队列的概念图,现在队列中只有数据 Blue。往队列中添加数据时,数据被加在最上面。 然后,队列中添加了数据 Green。往队列中添加数据的操作叫作 入队 。 紧接着,数据 Red 也入队了。 从队列中取出(删除)数据时,是从最下面,也就是最早入队的数据开始的,即 Blue。从队列中删除数据的操作叫作 出队 。 如果再进行一次出队操作,取出的就是 Green 了。 像队列这种最先进去的数据最先被取来,即 先进先出 的结构,我们称为 First In First Out,简称 FIFO 。 与栈类似,队列中可以操作数据的位置也有一定的限制。在栈中,数据的添加和删除都在同一端进行,而在队列中则分别是在两端进行的。队列也不能直接访问位于中间的数据,必须通过出队操作将目标数据变成首位后才能访问。 介绍完队列的基本知识后,接下来举一个例子,比如生活中常见的排队买票。 如何理解队列? 队列这个概念非常好理解,你可以把它想象成排队买票,先来的先买,后来的人只能站末尾,不允许插队,先进者先出,这就是典型的队列。

C语言面试题22. 链表中倒数第k个节点

孤人 提交于 2020-02-13 00:41:08
要求:输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。 示例: 给定一个链表: 1->2->3->4->5, 和 k = 2. 返回链表 4->5. 思路:定义快慢双指针,先让快指针先走k步,然后双指针一起移动,完成只需要遍历一遍 struct ListNode* getKthFromEnd(struct ListNode* phead, int k){ struct ListNode* pfast = phead ; struct ListNode* pslow= phead ; while(k--) { pfast=pfast->next ; } while(pfast!=NULL) { pslow=pslow->next; pfast =pfast->next; } return pslow ; } BTW 下面顺提一下我一开始的麻烦做法虽然也通过了不过是真的蠢 - - 先反转 然后找到反转的节点,接着再反转@@ 哈哈。还是要熟练运用快慢指针呀 struct ListNode* curr =phead ; struct ListNode* temp =NULL ; struct

新问题整理(高并发)

微笑、不失礼 提交于 2020-02-12 20:57:04
一、HashMap 是不是线程安全? HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中, 在多线程的环境下,存在同时其他的元素也在进行put操作,如果hash值相同,可能出现同时在同一数组下用链表表示,造成闭环,导致在get时会出现死循环,所以HashMap是线程不安全的 (多线程会导致 HashMap 的 node 链表形成环状的数据结构产生死循环) 1.1、如何变得安全: Hashtable:通过 synchronized 来保证线程安全的,独占锁,悲观策略。吞吐量较低,性能较为低下 ConcurrentHashMap:JUC 中的线程安全容器,高效并发。ConcurrentHashMap 的 key、value 都不允许为 null 1.2、jdk1.8相对于jdk1.7的优化 由 数组+链表 的结构改为 数组+链表+红黑树。 拉链过长会严重影响hashmap的性能,所以1.8的hashmap引入了红黑树,当链表的长度大于8时,转换为红黑树的结构 优化了高位运算的hash算法:h^(h>>>16) 将hashcode无符号右移16位,让高16位和低16位进行异或。 二、ConcurrentHashMap 的实现方式 1.7

List、Set、数据结构、Collections

浪子不回头ぞ 提交于 2020-02-12 19:38:34
List、Set、数据结构、Collections 数据结构 常见的数据结构 数据存储的常用结构有: 栈、队列、数组、链表和红黑树 栈 栈 : stack ,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。 简单的说:采用该结构的集合,对元素的存取有如下的特点 先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。 栈的入口、出口的都是栈的顶端位置。 需要注意两个名词: 压栈 :就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。 弹栈 :就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置。 队列 队列 : queue ,简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。 简单的说,采用该结构的集合,对元素的存取有如下的特点: 先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,小火车过山洞,车头先进去,车尾后进去;车头先出来,车尾后出来。 队列的入口、出口各占一侧。例如,下图中的左侧为入口,右侧为出口。 数组 数组 :

PAT Basic 1075 链表元素分类(25) [链表]

时光总嘲笑我的痴心妄想 提交于 2020-02-12 19:03:18
题目 给定⼀个单链表,请编写程序将链表元素进⾏分类排列,使得所有负值元素都排在⾮负值元素的前⾯,⽽[0, K]区间内的元素都排在⼤于K的元素前⾯。但每⼀类内部元素的顺序是不能改变的。例如:给定链表为 18→7→-4→0→5→-6→10→11→-2,K为10,则输出应该为-4→-6→-2→7→0→5→10→18→11。 输⼊格式: 每个输⼊包含1个测试⽤例。每个测试⽤例第1⾏给出:第1个结点的地址;结点总个数,即正整数N(<= 105);以及正整数K (<=1000)。结点的地址是5位⾮负整数,NULL地址⽤-1表示。接下来有N⾏,每⾏格式为: Address Data Next 其中Address是结点地址;Data是该结点保存的数据,为[-105, 105]区间内的整数;Next是下⼀结点的地址。题⽬保证给出的链表不为空。 输出格式: 对每个测试⽤例,按链表从头到尾的顺序输出重排后的结果链表,其上每个结点占⼀⾏,格式与输⼊相同。 输⼊样例: 00100 9 10 23333 10 27777 00000 0 99999 00100 18 12309 68237 -6 23333 33218 -4 00000 48652 -2 -1 99999 5 68237 27777 11 48652 12309 7 33218 输出样例: 33218 -4 68237 68237 -6

图的存储结构之邻接表(详解)

有些话、适合烂在心里 提交于 2020-02-12 15:04:04
图的存储结构之邻接表(详解) 之前我们介绍过图的邻接矩阵存储法,它的空间和时间复杂度都是N2,现在我来介绍另外一种存储图的方法:邻接表,这样空间和时间复杂度就都是M。对于稀疏图来说,M要远远小于N2。先上数据,如下。 1 2 3 4 5 6 4 5 1 4 9 4 3 8 1 2 5 2 4 6 1 3 7 第一行两个整数n m。n表示顶点个数(顶点编号为1~n),m表示边的条数。接下来m行表示,每行有3个数x y z,表示顶点x到顶点y的边的权值为z。下图就是一种使用链表来实现邻接表的方法。 上面这种实现方法为图中的每一个顶点(左边部分)都建立了一个单链表(右边部分)。这样我们就可以通过遍历每个顶点的链表,从而得到该顶点所有的边了。使用链表来实现邻接表对于痛恨指针的的朋友来说,这简直就是噩梦。这里我将为大家介绍另一种使用数组来实现的邻接表,这是一种在实际应用中非常容易实现的方法。这种方法为每个顶点i(i从1~n)也都保存了一个类似“链表”的东西,里面保存的是从顶点i出发的所有的边,具体如下。 首先我们按照读入的顺序为每一条边进行编号(1~m)。比如第一条边“1 4 9”的编号就是1,“1 3 7”这条边的编号是5。 这里用u、v和w三个数组用来记录每条边的具体信息,即u[i]、v[i]和w[i]表示第i条边是从第u[i]号顶点到v[i]号顶点(u[i]àv[i]),且权值为w[i