链表

Java_Map集合接口

♀尐吖头ヾ 提交于 2020-02-16 10:02:31
现实生活中,我们经常需要成对存储某些信息。比如,我们使用的微信,一个手机号只能对应一个微信账户。这就是一种成对存储的关系。 Map就是用来存储“键(key)-值(value) 对”的。 Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复。 Map 接口的实现类有HashMap、TreeMap、HashTable、Properties等。 Map接口中常用的方法: HashMap采用哈希算法实现,是Map接口最常用的实现类。 由于底层采用了哈希表存储数据,我们要求键不能重复,如果发生重复,新的键值对会替换旧的键值对。 HashMap在查找、删除、修改方面都有非常高的效率。 Map接口中的常用方法 : import java.util.HashMap; import java.util.Map; public class TestMap { public static void main(String[] args) { Map<Integer, String> m1 = new HashMap<Integer, String>(); Map<Integer, String> m2 = new HashMap<Integer, String>(); m1.put(1, "张三"); m1.put(2, "李四"); m1.put(3, "王五"); m2.put(1, "一

LeetCode 2 - 两数相加

蓝咒 提交于 2020-02-16 03:59:36
题目描述 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 解法一:Python 把链表转化为数字进行求和后在返回成链表,当然这道题有些处心积虑的是如果用C/C++这个方法就不得行,因为其中有测试样例超出了int的长度,但是对Python来说可以全然不顾。当然这个方法也是最为简便的方法,既不用考虑进位,也不用担心两数字长度不一要补0. # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution : def addTwoNumbers ( self , l1 : ListNode , l2 : ListNode ) - > ListNode : def get_num ( l ) : if not l : return 0 return l

集合Set

只谈情不闲聊 提交于 2020-02-16 02:59:21
集合的一个关键的特点就是不能存放重复的元素,二分搜索树是一个非常好的实现集合的底层数据结构 1、二分搜索树实现集合: set接口 package Set ; public interface Set < E > { void add ( E e ) ; boolean contains ( E e ) ; void remove ( E e ) ; int getSize ( ) ; boolean isEmpty ( ) ; } BST.class package Set ; import java . util . LinkedList ; import java . util . Queue ; import java . util . Stack ; public class BST < E extends Comparable < E >> { private class Node { public E e ; public Node left , right ; public Node ( E e ) { this . e = e ; left = null ; right = null ; } } private Node root ; private int size ; public BST ( ) { root = null ; size = 0 ; }

用数组模拟链表(C++)

二次信任 提交于 2020-02-16 01:24:52
静态链表 单链表 双链表 用数组模拟链表,因为结构体方式实现非常慢,做题时用数组更方便操作且快 单链表 # include <iostream> using namespace std ; const int N = 100010 ; int head , idx , e [ N ] , ne [ N ] ; //e[N]存data,ne[N]存指针指向的结点下标 //初始化 void init ( ) { head = - 1 ; //头结点下标 idx = 0 ; //一个指针,指向存储当前使用的结点 } //将x插入到头结点 void add_head ( int x ) { //e[N]存data,ne[N]存指针指向的结点下标 e [ idx ] = x , ne [ idx ] = head , head = idx , idx ++ ; } //将x插到下标是k的点后面 void add ( int k , int x ) { e [ idx ] = x , ne [ idx ] = ne [ k ] , ne [ k ] = idx , idx ++ ; } //将下标是k的点后面的点删掉 void remove ( int k ) { ne [ k ] = ne [ ne [ k ] ] ; //直接指向被删除点后面的点 } int main ( ) { ios

算法基础—数据结构—单链表

巧了我就是萌 提交于 2020-02-16 01:21:03
对于链表我想大家应该都不陌生,但是再算法里面,一般以静态链表为准(数组模拟链表)。主要是因为快。 这里总结了基本算法用到的一些模板,不出意外应该就这些,再看代码的时候希望画图理解qwq // head存储链表头,e[]存储节点的值,ne[]存储节点的next指针,idx表示当前用到了哪个节点 int head, e[N], ne[N], idx; //初始化 int intx(){ head = -1; idx = 0; } // 在链表头插入一个数 int add_head(int x){ e[idx] = x; ne[idx] = head; head = idx++; } //将头结点删除,保证头结点存在 int remove(){ head = ne[head]; } //在链表中插入一个数 int add(int k,int x){ e[idx] = x; ne[idx] = ne[k]; ne[k] = idx++; } //再链表中删除一个数 int remove_d(int k){ ne[k] = ne[ne[k]] } 直接根据题目来看吧。 https://www.acwing.com/problem/content/828/ 题目要求就是根据不同的操作来模拟链表,最后遍历输出。 #include<bits/stdc++.h> using namespace

链表(LInked LIst)——链表介绍

风格不统一 提交于 2020-02-16 00:23:02
Linked Lists (链表) 链表是一种线性数据结构,链表中的每一个元素都是一个单独的对象,我们将其称之为节点。每个节点包含一个数据域和一个指向下一个节点的指针域。这些节点可能存储在内存中的不同位置,而不像数组那样存储在连续的内存空间中。 链表中可以存储类似于数组的数据,但是相比数组,链表在存储上具有更多优势。 想象以下人的关系链。如果A认识B,B认识C,那么C就可以通过这个连接链接到A。每个人都可以被视为认识下一个人的节点。 在C语言中,我们定义一个包含数据域和指针域的Node如下: struct Node { int data ; int Node * next ; } 与数组相比具有的优势 与数组相比,链表具有以下两大优势: 没有固定大小 链表不需要固定内存大小。当创建一个新节点时,将动态分配用于存储节点的内存位置。没有使用的位置不会占据内存地址。与数组相比,数组智能一次性固定内存大小,且扩充或者缩减数组时代价会非常昂贵。 插入和删除效率极高 在节点之间进行快速删除和插入所花费的时间恒定。相反,处理数组时,插入和删除需要遍历数组中的所有元素。 算法复杂度 Access Search Insertion Deletion Space O(n) O(n) O(1) O(1) O(n) 与数组相比具有的劣势 与数组相比,使用链表存在一些缺点 仅能通过线性访问

[LeetCode] 61. Rotate List

一个人想着一个人 提交于 2020-02-15 19:44:04
1. 原题链接: https://leetcode.com/problems/rotate-list/ 2. 解题思路 对于链表涉及到反转、倒置等操作,一般都需要两个指针:prev、cur 根据翻转的规则,当翻转次数刚好是链表长度list_len的整数倍时,实际上翻转后的链表和未翻转的原链表是一样的 翻转次数k >= 0,由于k的大小不确定,当k是list_len的整数倍时,直接返回(因为通过k次翻转后,还是和原链表一样);否则,实际需要翻转的次数times是:(k % list_len) 因此,prev指向第(list_len - times)个节点,cur指向第(list_len - times + 1)个节点 采用头插法将cur指向的链表插入到原链表的头部 3. 算法 统计链表长度为list_len 判断k是不是list_len的整数倍 确定prev指针的位置,也就是第(list_len - times)个节点 确定cur指针的位置,也就是prev->next指向的节点 找到原链表的尾节点tail 采用头插法进行翻转 4. 实现 struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: ListNode*

双链表

时光怂恿深爱的人放手 提交于 2020-02-15 18:46:18
1 #ifndef _LIST_H_ 2 #define _LIST_H_ 3 //虚基类 4 template<class ElemType> 5 class List 6 { 7 public: 8 List() {}; 9 virtual ~List() {}; 10 virtual void Clear() = 0;//清空数据结构 11 virtual void Insert(const int& i, const ElemType& X) = 0;//插入元素 12 virtual void ReMove(const int& i) = 0;//移除指定位置的元素 13 virtual void Erase(const ElemType& X) = 0;//删除表中所有X元素 14 virtual int Search(const ElemType& X) const = 0;//搜索某个元素 15 virtual void Traverse() const = 0;//遍历数据结构 16 virtual ElemType Visit(const int& i)const = 0;//访问某个元素 17 }; 18 #endif // !_LIST_H_ List.h 1 #ifndef __DLINKLIST_H__ 2 #define __DLINKLIST_H__

leetcode-24 两两交换链表中的节点

我的未来我决定 提交于 2020-02-15 14:13:16
题目描述 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 方法一(递归): 将配对交换过程拆解为多个以两个元素为一对的子问题 …n(k-1) -> n(k)->n(k+1)->… 假如n(k+1)之后已经完成逆置,此时置换之后…->n(k-1)->n(k+1)->n(k)->… Node *p = head -> next; head -> next = p -> next; p -> next = head; 实现如下: ListNode * swapPairs ( ListNode * head ) { if ( head == NULL || head -> next == NULL ) { return head ; } ListNode * p = head -> next ; head -> next = swapPairs ( p -> next ) ; p -> next = head ; return p ; } 方法二(非递归): 构造一个虚拟的头节点,同时当前链表遍历的结束条件: 如果链表长度为偶数,那么p->next->next = NULL 如果链表长度为奇数,那么p->next = NULL

剑指offer打卡|两个链表的第一个公共结点

我们两清 提交于 2020-02-15 10:09:38
题目描述 输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的) 代码 公共结点是啥:并不是两个节点的值相同就是公共节点,而是在第一链表和第二链表中都存在一个节点,该节点往后的子链表在两个链表中是相同的。如下图中的6就是第一个公共结点。 设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。 当访问链表 A 的指针访问到链表尾部时,令它从链表 B 的头部重新开始访问链表 B;同样地,当访问链表 B 的指针访问到链表尾部时,令它从链表 A 的头部重新开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。 /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { if(pHead1==null||pHead2==null){ return null; } ListNode l1