查找算法

java数组、List、Set、Map

陌路散爱 提交于 2019-12-25 17:53:10
数组是 Java 语言内置的类型,除此之外,Java有多种保存对象引用的方式。Java类库提供了一套相当完整的容器类,使用这些类的方法可以保存和操纵对象。下面分别进行讨论,在研究Java容器类之前,先了解一下Java数组的基本功能和特性。 1. 数组的基本特性 数组与 其它 种类的容器(List/Set/Map)之间的区别在于效率、确定的类型和保存基本类型数据的能力。数组是一种高效的存储和随机访问对象引用序列的方式,使用数组可以快速的访问数组中的元素。但是当创建一个数组对象(注意和对象数组的区别)后,数组的大小也就固定了,当数组空间不足的时候就再创建一个新的数组,把旧的数组中所有的引用复制到新的数组中。 Java中的数组和容器都需要进行边界检查,如果越界就会得到一个RuntimeException异常。这点和C++中有所不同,C++中vector 的操作符[]不会做边界检查,这在速度上会有一定的提高,Java的数组和容器会因为时刻存在的边界检查带来一些性能上的开销。 Java中通用的容器类不会以具体的类型来处理对象,容器中的对象都是以Object类型处理的,这是Java中所有类的基类。另外,数组可以保存基本类型,而容器不能,它只能保存任意的Java对象。 一般情况下,考虑到效率与类型检查,应该尽可能考虑使用数组。如果要解决一般化的问题,数组可能会受到一些限制

LeetCode 34 在排序数组中查找元素的第一个和最后一个位置

与世无争的帅哥 提交于 2019-12-25 01:00:52
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1] 这道题也是用两次二分就可以解决,开始位置的判断性质是,满足大于等于target条件的第一个数。如果找到的这个数不等于target,说明目标值不存在,直接返回 [-1, -1]。结束位置的判断性质是,满足小于等于target条件的最后一个数。 c++代码如下: 1 class Solution { 2 public: 3 vector<int> searchRange(vector<int>& nums, int target) { 4 if(nums.empty()) return {-1, -1}; 5 int l = 0, r = nums.size() - 1; 6

白盒密码技术

偶尔善良 提交于 2019-12-24 21:50:14
白盒密码技术 White-Box Cryptography 主要参考材料:<<白盒密码的设计与研究 >> 来学嘉;肖雅莹,2009; 白盒攻击 白盒攻击环境指的是密码软件的执行对攻击者完全可见的环境。在白盒攻击环境中,攻击者通过观察或者 执行密码软件,很容易就可以获得密钥信息。白盒密码是针对这种环境提出来的,其目的是为了在白盒攻击环境中,有效地防止攻击者获得密钥信息; 主要思想是:对于一个密码算法,给定一个特定的密钥后,明文到密文的映射也就确定了,然后把 明文到密文的映射进行置乱编码(Encoding),将加密后得到的映射用查找表的形式表示,密码算法的执行过程就通过查找表格来实现。这些查找表是与密钥相关的,密钥隐藏在表格中,但是攻击者根据查找表无法得出密钥信息。查找表的实现方式为白盒攻击环境中密钥的保护提供了一个新的解决方案; 思想小结: 简单来说,在移动终端中,运行一个密码算法,算法,明文,秘钥都在终端上,当敌手控制这个终端的时候,就很容易得到秘钥,为了保护秘钥的安全,所以需要想办法将秘钥隐藏进算法中,使用秘钥和算法建立一个明文和密文的查找表。然后加密,解密时直接进行查表就行;相应的,对称和非对称的实现过程应该还需要具体的实现方式; 白盒密码的安全性分析 白盒密码的主要目的是为了在白盒攻击环境中防止攻击者从密码算法的执行过程中抽取出密钥。白盒密码的密钥信息隐藏在查找表中

Hash算法

人走茶凉 提交于 2019-12-24 00:56:04
  Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的 消息摘要 的函数。   HASH主要用于信息安全领域中加密算法,它把一些不同长度的信息转化成杂乱的128位的编码,这些编码值叫做HASH值. 也可以说,hash就是找到一种数据内容和数据存放地址之间的映射关系 基本概念    * 若结构中存在和关键字K相等的记录,则必定在f(K)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f为 散列函数 (Hash function),按这个思想建立的表为 散列表 。   * 对不同的关键字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),这种现象称冲突。具有相同函数值的关键字对该散列函数来说称做同义词。综上所述,根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象” 作为记录在表中的存储位置,这种表便称为散列表,这一映象过程称为散列造表或散列,所得的存储位置称散列地址。   *

《数据结构与算法》-2-线性表

我的梦境 提交于 2019-12-23 13:24:02
目录 1. 线性表的定义和基本操作 1.1 线性表的定义 1.2 线性表的基本操作 2. 线性表的顺序表示 2.1 顺序表的定义 2.2顺序表上基本操作的实现 3. 线性表的链式表示 3.1 单链表的定义 3.2 单链表基本操作的实现 3.3 双链表 3.4 循环链表 3.5 静态链表 4. 顺序表与链表的比较 5. 如何选择存储结构   该系列博客的目的是为了学习一遍数据结构中常用的概念以及常用的算法,为笔试准备;主要学习过程参考王道的《2018年-数据结构-考研复习指导》; 已总结章节: 《数据结构与算法》-1-绪论 《数据结构与算法》-2-线性表   上篇博客 《数据结构与算法》-1-绪论 中说到数据结构的三要素:逻辑结构、存储结构、数据的运算;其中,逻辑结构表示的是数据元素之间的关系,逻辑结构根据数据元素之间关系的不同,分成了线性结构与非线性结构,这里我们将要介绍的就是线性结构中的线性表,并根据线性表在计算机中存储结构的不同,分别介绍了:顺序存储(顺序表)、链式存储(链表);   这篇主要介绍的内容有: 线性表的定义以及基本操作 ; 线性表的顺序存储 ; 线性表的链式存储 ; 顺序表与链表的比较 ;   其知识框架如下图所示: 1. 线性表的定义和基本操作   这一节主要介绍线性表,主要内容包括:线性表的定义及基本操作; 1.1 线性表的定义   定义: 线性表是具有 相同

09-03 继承与派生

旧街凉风 提交于 2019-12-23 10:01:35
文章目录 二 继承与抽象 三 属性查找 四 继承的实现原理 五 派生与方法重用 六 组合 #一 继承介绍 继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,新建的类可称为子类或派生类,父类又可称为基类或超类 class ParentClass1 : #定义父类 pass class ParentClass2 : #定义父类 pass class SubClass1 ( ParentClass1 ) : #单继承 pass class SubClass2 ( ParentClass1 , ParentClass2 ) : #多继承 pass 通过类的内置属性__bases__可以查看类继承的所有父类 >> > SubClass2 . __bases__ ( < class '__main__.ParentClass1' > , < class '__main__.ParentClass2' > ) 在Python2中有经典类与新式类之分,没有显式地继承object类的类,以及该类的子类,都是经典类,显式地继承object的类,以及该类的子类,都是新式类。而在Python3中,即使没有显式地继承object,也会默认继承该类,如下 >> > ParentClass1 . __bases__ ( < class ‘ object ' > , ) >> >

程序员必知8大排序3大查找

心不动则不痛 提交于 2019-12-22 17:01:57
每天都在叫嚣自己会什么技术,什么框架,可否意识到你每天都在被这些新名词、新技术所迷惑,.NET、XML等等技术固然诱人,可是如果自己的基础不扎实,就像是在云里雾里行走一样,只能看到眼前,不能看到更远的地方。这些新鲜的技术掩盖了许多底层的原理,要想真正的学习技术还是走下云端,扎扎实实的把基础知识学好,有了这些基础,要掌握那些新技术也就很容易了。 要编写出优秀的代码同样要扎实的基础,如果排序和查找算法学的不好,怎么对程序的性能进行优化?废话不多说,本文要介绍的这些排序算法就是基础中的基础,程序员必知! 1、直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数 也是排好顺序的。如此反复循环,直到全部排好顺序。 (2)实例 2、希尔排序(也称最小增量排序) (1)基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。 (2)实例: 转自csdn博客点击查看详情 来源: https://www.cnblogs.com/yudanmomo/archive/2012/05/07

非算法工程师面试必问的算法面试理论

帅比萌擦擦* 提交于 2019-12-22 02:58:12
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 非算法方向的你 面了多少次试? 最后,因为不懂算法, 死在了半路上? 这些痛, 作为技术创新型公司的小编——个推君 怎么会不懂? 为此,个推君特请了我司经验丰富的面试官 为你奉上一份热乎的 面试宝典 。 宝典可不是面试题哦 仅送给想认真钻研的童鞋 帮大家梳理知识点 让大家举一反三, offer拿到手软! 注:此处建议大家使用 C 语言来学习数据结构与算法。 一、数据结构 数据结构是算法的基础。大家需要对数据结构有个清晰的概念,因为大部分的算法题均需要带入数据结构的概念来处理。科班出身的程序员或多或少学习过数据结构。我们推荐大家可以重温下这本书,温故而知新。 时间复杂度与空间复杂度 在说算法之前和大家科普两个重要的理论知识:算法的时间复杂度与空间复杂度。 时间复杂度 算法的时间复杂度,用来度量算法的运行时间,记作: T(n) = O(f(n))。它表示随着 输入大小n 的增大,算法执行需要的时间的增长速度可以用 f(n) 来描述,并且会忽略常量部分。 举个例子 int aFunc(void) { printf("Hello, World!\n"); // 需要执行 1 次 return 0; // 需要执行 1 次} 调用此方法,printf("Hello, World!\n"); 执行了一次,那么我们记作 T

C++ STL算法系列2---find ,find_first_of , find_if , adjacent_find的使用

主宰稳场 提交于 2019-12-22 02:11:10
一.find运算 假设有一个int型的vector对象,名为vec,我们想知道其中 是否包含某个特定值 。 解决这个问题最简单的方法时使用标准库提供的find运算: 1 // value we'll look for 2 int search_value = 42; 3 4 //call find to see if that value is present 5 vector<int>::const_iterator result = find(vec.begin() , vec.end() , search_value); 6 7 //report the result 8 cout<<"The value "<<search_value 9 <<(result == vec.end() ? " is not present" : "is present") 10 <<endl; 具体实现代码: 1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 6 int main() 7 { 8 // value we'll look for 9 int search_value = 42; 10 int ival; 11 vector<int> vec; 12 13

数据结构之查找运算

Deadly 提交于 2019-12-20 07:26:38
查找运算 查找 线性表的查找 顺序查找(都是从后往前找) 折半查找(二分查找) 分块查找(索引顺序查找) 数表的查找 哈希表(散列表的查找) 查找 查找表可分为两类 静态查找表 仅作查询和检索操作的查找表。 动态查找表 有时在查询之后,还需要将“查询”结果为“不在查找表中”的数据元素插入到查找表中;或者,从查找表中删除其“查询”结果为“在查找表中”的数据元素。 关键字 是数据元素(或记录)中某个 数据项 的值,用以标识(识别)一个数据元素(或记录)。 若此关键字可以识别唯一的一个记录,则称之谓“主关键字”。 若此关键字能识别若干记录,则称 之谓“次关键字”。 线性表的查找 顺序查找(都是从后往前找) 顺序查找方法既适用于线性表的 顺序存储结构 ,又适用于线性表的 链式存储结构 。( 无序 ) 时间复杂度为O(n)。 在不等概率查找的情况下,ASLss 在 Pn≥Pn-1≥···≥P2≥P1时取极小值 若查找概率无法事先测定,则查找过程采取的改进办法是,在每次查找之后,将刚刚查找到的记录直接移至表尾的位置上。 折半查找(二分查找) 折半查找要求线性表必须才用 顺序存储结构 ,而且表中元素按关键字 有序 排列。 时间复杂度为O(log2 n)。 算法步骤: 置查找区间初值,low为1,high为表长。 当low小于等于high时,循环执行以下操作: mid取值为low和high的中间值