链表

25. Reverse Nodes in k-Group

一个人想着一个人 提交于 2020-02-13 20:43:34
今天份的困难题 文章目录 题目 分析 代码 题目 给定一个链表,一次反转链表k个节点,并返回修改后的链表。 其中k是正整数,如果剩下链表的长度不足k的话,返回原来的样子 例子: Given this linked list: 1->2->3->4->5 For k = 2, you should return: 2->1->4->3->5 For k = 3, you should return: 3->2->1->4->5 分析 对于反转链表的题目已经做了不少了,这题算是普通链表的升级版,主要就是分析相比于普通的链表我们需要多知道哪些信息。 以下面的链表为例,k=2,1->2->3->4->5 首先我们肯定需要用到dummy,dummy.next = head,用来储存我们需要返回的值。 首先,我们需要判断这个链表的节点满足我们反转的要求,令r为我们需要反转部分的第一个节点,如果它往后走k个节点始终没有走到空节点的话,那么就满足反转的条件,而r节点同时也走到了下一个需要反转部分的开始节点。 首先我们从第一部分开始反转,如果l同样是需要反转部分的开始节点,令 pre, cur= l, l.next 即可,然后就是标准的反转过程,如果k=2的话,反转两个节点,就是进行1次。 那么,现在的链表为: dummy->1<- (-> )2 3->4->5 然后 pre 节点指向2, cur

反转链表

℡╲_俬逩灬. 提交于 2020-02-13 17:41:22
题目描述: 输入一个链表,反转链表后,输出新链表的表头。 代码描述: /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode ReverseList ( ListNode head ) { // 判断链表为空或长度为1的情况 if ( head == null || head . next == null ) { return head ; } ListNode pre = null ; // 当前节点的前一个节点 ListNode next = null ; // 当前节点的下一个节点 while ( head != null ) { next = head . next ; // 记录当前节点的下一个节点位置; head . next = pre ; // 让当前节点指向前一个节点位置,完成反转 pre = head ; // pre 往右走 head = next ; // 当前节点往右继续走 } return pre ; } } 来源: CSDN 作者: yiyiyuebing 链接: https://blog.csdn.net/baidu

金三银四,收下这份最全安卓开发面试指南!

天涯浪子 提交于 2020-02-13 17:28:21
引言 时间匆匆而过,2020已经过了43天,虽然开局不利,但是我们要怀着一颗积极向上的心,来面对未来每一天的挑战! 现在只是一些小考验,我们要相信未来是美好的,做好充足准备去迎接面试的黄金期,加油! 所谓“兵马未动,粮草先行”,我们打响明天的战役也需要精神食粮来做后勤保障才是。 在此我整理了一份安卓开发面试指南,希望对磨砺锋芒、奋发向上的小伙伴有所帮助,祝你早日剑指大厂,扬帆起航,奥利给! Java基础 Java集合框架 Java集合——ArrayList Java集合——LinkedList Java集合——HashMap Java集合——TreeMap Java集合——LinkedHashMap Java泛型 Java反射(一) Java反射(二) Java反射(三) Java注解 Java IO(一) Java IO(二 ) RandomAccessFile Java NIO Java异常详解 Java抽象类和接口的区别 Java深拷贝和浅拷贝 Java transient关键字 Java finally与return执行顺序 Java 8 新特性 Java并发 Java创建线程的三种方式 Java线程池 死锁 Synchronized/ReentrantLock 生产者/消费者模式 volatile关键字 CAS原子操作

142. 环形链表 II

感情迁移 提交于 2020-02-13 17:03:17
该题旨在判断给定的链表是否存在环,若存在,则返回环的起始节点。 方法一: 利用哈希集记录已访问过的节点,当发生重复访问时,则表示链表中存在环,并返回第一个重复的节点,若没有发现重复元素,则表示该链表中没有换,返回null。 public class Solution { public ListNode detectCycle ( ListNode head ) { Set < ListNode > visited = new HashSet < ListNode > ( ) ; ListNode node = head ; while ( node != null ) { if ( visited . contains ( node ) ) { return node ; } visited . add ( node ) ; node = node . next ; } return null ; } } 方法二: 利用双指针法,慢指针一次后移一个节点,快指针一次后移两个节点; 当两个指针相遇时,令快指针指向头结点,并让两个指针都逐次后移一个节点; 当两个指针第二次相遇时,他们相遇的节点即为链表中环的起始节点。 该方法详细的数学分析过程可以参考文章: 环形链表 II(双指针法,清晰图解) public class Solution { public ListNode

数据结构之链表定义及基本操作实现

对着背影说爱祢 提交于 2020-02-13 14:06:30
  在我上一篇的博客中说过,数据结构的线性结构中有连续存储结构和离散存储结构,这次就写一写学习离散存储结构——链表的小总结。   首先说一下链表的定义:链表是物理存储单元上非连续、非顺序的存储结构,链表的结点间通过指针相连,每个结点只对应有一个前驱结点和一个后继结点,其中,首结点没有前驱结点,尾节点没有后继结点。上述表述共同构成了对链表的定义。   接下来说一下链表的结构:链表由头结点+有效节点构成,其中有效节点由分为首结点、普通节点、尾节点。 头结点:链表中有效结点前面的结点,头结点并不存放实际数据,仅仅是为了方便对链表的操作。 头指针:头结点并没有什么实际的含义,仅仅是为了方便对链表的操作,而头指针,顾名思义,就是指向头结点的指针。我们通过头指针指向的头结点的指针域对链表进行操作。 首结点:链表的第一个有效的结点。 尾结点:链表中最后一个有效的结点,尾结点的指针域为空。   链表已经学习完毕,那么接下来就是要说一下链表的构成——结点。因为链表是一张离散存储的结构,所以就需要通过地址去访问,那么久需要在结点中保存下一个结点的地址。还是用到c语言中的结构体。 1 //定义链表的节点 2 typedef struct Node{ 3 //数据域 4 int data; 5 //指针域 6 struct Node * pNext; 7 }NODE,*PNODE;   结点定义完毕后

数据结构(二) -- 数组和链表

一曲冷凌霜 提交于 2020-02-13 14:04:37
/*--> */ /*--> */ /*--> */ /*--> */ 数据结构(二) -- 数组和链表 数据结构主要可以分为两大模块: 线性结构 非线性结构 本文主要开始讲线性结构。 什么是线性结构 线性结构,顾名思义,就是这些数据所有节点都能被一根线(指针)联系起来的一种结构。 线性结构的存储方式: 连续存储:【数组】 离散存储:【链表】 线性结构的常见应用方式: 栈 队列 专题 :【递归】 数组和链表 本小节学习数组和链表,从底层去了解和实现数组与链表,并分析两者对应的优缺点 数组 数组是最常见的链式存储结构,它是一段连续的内存空间,在内存中我们可以简单表示为下图样式 通过上图我们可以把代码中 int arr[6] = {1,2,3,4,5,6}; 执行的操作从内存中脑补出来,同时我们可以简单分析一下,数组应该有的一些基本使用。如 初始化、 添加新元素、 插入新元素、 删除某个元素、 判断是否为空数组、 是否是满数组、 排序 倒序 查询是否包含某个元素 ······ 本小节就带着你手把手实现一个简单的数组的封装,借此来了解数组的数据结构以及内部的一些基本算法知识。这里就简单的以一个 int 类型的数组来示例,后面学到泛型的时候便可更加好的理解数组的实现。 首先简单分析一下数组中基本的属性,我们有上面的数组内存中的逻辑图可以确定数组有对应的内存空间,有一个内存起始地址

STL学习记录:链表

寵の児 提交于 2020-02-13 12:22:48
直接百度链表的话,其实和真正用起来的STL链表差的挺远的(毕竟有些情况能用就行~),还是自己写一下记录一下STL里链表具体用法吧 #include <bits/stdc++.h> using namespace std; int main () { //1. 定义 //list<数据类型> 链表名称 list<int> test; list<int>::iterator iter=test.begin(); //2. 增删改查 //增加 test.push_front(1); //向头部增加元素 test.push_back(10); //向尾部增加元素 test.insert(iter,2,3); //向指定位置(迭代器位置)增加几个元素 //删除 test.pop_back(); //删除尾部元素 test.pop_front(); //删除头部元素 test.remove(1); //删除特定元素 test.unique(); //删除相邻重复元素 test.clear(); //改 test.sort(); //排序 test.reverse(); //反转 //查 test.empty(); //如果空链表,返回值为真 int howmany2=count(test.begin(),test.end(),2); //查有多少个2 iter=find(test.begin(

数据结构一:链表(linux链表)

邮差的信 提交于 2020-02-13 11:25:00
一:实现机制 linux链表实现思想就是:结点里面只创建一个next指针,用指针将各个结点相连接 打印和查找的时候,再进行类型的转换 二:代码 1 LinkList.h /* LinkList.h linux链表实现思想就是:结点里面只创建一个next指针,用指针将各个结点相连接 打印和查找的时候,在进行类型的转换 */ # ifndef _LINKLIST_H_ # define _LINKLIST_H_ # include <stdlib.h> # include <stdio.h> //链表小结点 和普通链表相比较 没有数据域 只有next指针 typedef struct LINNODE { struct LINNODE * next ; } Link_Node ; //链表,有头结点和长度 typedef struct LINKLIST { Link_Node head ; // Link_Node的结构体,而不是结构体指针 int size ; //结点个数 } Link_List ; //查找回调函数 typedef int ( * FIND ) ( Link_Node * data1 , Link_Node * data2 ) ; //打印回调函数 typedef void ( * PRINT ) ( Link_Node * data ) ; //初始化 Link

HashMap(一)基础入门

人盡茶涼 提交于 2020-02-13 10:58:13
1.数组的优势/劣势 数组的内存空间是连续的 特点:索引速度快 劣势:增加、删除数据时,浪费性能 2.链表的优势/劣势 链表不是连续的内存,每一块内存中有一个引用保存下一个内存的地址。 优势:增加、删除数据时,效率高 劣势:如果要访问最后一个元素,只能从头依次访问每一个内存,查询效率低 3.有没有一种方式整合两种数据的优势? 散列表。 整合了数组的快速索引,和链表的动态扩容 4.什么是哈希? 核心理论:Hash也称散列、哈希,基本理论就是把 任意长度 的输入,通过Hash算法变成 固定长度 的输出。 这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就是哈希值。 Hash的特点: 从hash值不可以反向推导出原始的数据 输入的数据的微小变化会得到完全不同的hash值,相同的数据会得到相同的值 哈希算法的执行效率高效,长的文本也能快速计算出哈希值。 hash算法的冲突概率要小 由于hash的原理是将输入空间的值映射成hash空间内,而hash值的空间远小于输入的空间。 根据抽屉原理,一定会在不同的输入被映射成相同输出情况。 抽屉原理:桌上有十个苹果 ,要把这十个苹果放到九个抽屉里,无论怎么放,我们会发现至少会有一个抽屉里面放不少于两个苹果。 这一现象就是我们所说的“抽屉原理” 来源: CSDN 作者: 梨子果果哟 链接: https://blog.csdn.net/qq

线性表--队列

心已入冬 提交于 2020-02-13 03:49:47
和栈相反,队列是一种先进先出(first in first out 缩写为FIFO)的线性表。它只允许在表的一端进行插入,而在另一端删除元素。 双端队列:限定插入和删除操作在表的两端进行的线性表 -----单链队列 队列的链式存储表示------ 和线性表类似,队列也可以有两种存储表示。用链表表示的队列简称链队列。 typedef struct QNode { QElemType data; struct QNode * next; }QNode ,QueuePtr; typedef struct { Queueptr front; //队头指针 Queueptr rear; //队尾指针 }LinkQueue; status InitQueue(LinkQueue & q) { //构造一个带头结点的空队列   q.front = q.rear = (Queueptr) malloc ( sizeof(QNode));   if(!q.front) exit;   q.front->next = NULL;   return ok; } status DestroyQueue(LinkQueue & q) {   while(q.front)   {     q.rear= q.front->next;     free(q.front);     q.front = q