数据结构与常用算法

  1. 找出数组中出现次数超过一半的数 参考1 参考二
#include <iostream>
using namespace std;
int search(int a[], int n)
{
	int save = 0;  //令save表示要保存下来的数
	int count = 0; //用来计数
	for (int i = 0; i < n; i++)
	{
		if (count == 0)
		{
			save = a[i];
			count = 1;
		}
		else if (a[i] == save) //当前数字与save相同
		{
			count++;
		}
		else if (a[i] != save)
		{
			count--;
		}
	}
	return save;
}
int main()
{
	int A[6] = {1, 2, 2, 1, 1, 1};
	int B[7] = {1, 0, 1, 0, 0, 1, 1};
	int C[7] = {3, 4, 6, 3, 3, 3, 7};
	cout << search(A, 6) << endl;
	cout << search(B, 7) << endl;
	cout << search(C, 7) << endl;
	return 0;
}

思路:求数组中个数超过一半的数,就是说它出现的次数比其他所有数字出现次数的和还要多。令save表示当前要保存的数,令count记录次数,初始值为0。遍历数组,如果count为0,则保存当前数字,并把count置为1。因为次数为0,表示前面是字符串计数抵消为0。如果下一个数字和我们之前保存的数字相同,则次数加1;如果下一个数字和我们之前保存的数字不同,则次数减1(抵消一个个数)。

  1. 数组和链表的区别
  1. 逻辑结构:链表是链式的存储结构,数组是顺序的存储结构。数组是一块连续的空间,在声明时就要确定它的长度。链表是一块可以不连续的动态空间,长度可变。
  2. 内存存储:数组若采用静态分配,则在栈上分配空间。若使用new的方式动态创建,是在堆上分配内存。
  3. 访问方式:数组在内存中是连续的存储,因而可以通过下标索引访问。链表是链式存储结构,在访问元素的时候只能通过先行方式从前到后访问,所以访问效率比数组低。但是链表可以快速进行数据的插入和删除,而数组进行插入和删除时可能需要移动大量元素。
  1. 有几种程序内存分配方式:

一个由C/C++编译程序占用内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数参数值,局部变量值等。其操作方式类似于数据结构中栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量存储是放在一块,初始化全局变量和静态变量在一块区域, 未初始化全局变量和未初始化静态变量在相邻另一块区域。 - 程序结束后由系统释放。–>分别是data区,bbs区
4、文字常量区 —常量字符串就是放在这里。 程序结束后由系统释放–>coment区
5、程序代码区—存放函数体二进制代码。–>code区

  1. 数据的逻辑存储结构(如数组,队列,树等)对于软件开发具有十分重要的影响,试对你所了解的各种存储结构从运行速度,存储效率和适用场合等方面进行简要地分析。
运行速度存储效率适用场合
数组适合进行查找操作
链表较快较高适合增删改频繁操作,动态的分配内存
较快一般一般具有层次关系的都可以用树来描述
一般一般最小生成树,最短路径,拓扑排序,神经网络
队列较快较高适合进行任务类的调度
一般较高适合递归类程序的改写
  1. HashMap和HashTable的区别
  1. HashMap是基于HashTable实现的。不同之处在于HashMap允许null(null value和null key)。HashTable不允许null。
    在这里插入图片描述
  1. hash冲突的解决办法
  1. 开放地址法:当发生冲突时,以某种探测技术在散列表中形成一个探测序列。沿此序列逐个单元寻找,直到找到给定的关键字,或者碰到一个开放的地址,将待插入的新结点存入该单元。
  2. 再哈希法:这种方法是同时构造多个不同的哈希函数:
    H i = R H 1 ( k e y ) , i = 1 , 2 , . . . , k H_i=RH1(key),i=1,2,...,k Hi=RH1(key),i=1,2,...,k。当哈希地址 H i = R H 1 ( k e y ) H_i=RH1(key) Hi=RH1(key)发生冲突时,再计算 H i = R H 2 ( k e y ) Hi=RH2(key) Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。
  3. 链地址法:散列表的每个地址都是一个链表的表头,关联着一个链表结构。散列到相同地址的记录都放在这个地址关联的链表中。适用于经常进行插入和删除的情况。
  4. 建立公共溢出区:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。
  1. 栈”的实现(用数组和链表怎么实现) 参考
  1. 栈的特点是先入后出。包含两种重要操作push和pop。
  2. 数组实现:利用一个变量count用来记录栈顶下标,通过改变栈下标值来模拟出入栈。
  3. 链表实现依靠表头指针作为栈顶指针,采用头插法进入push和pop操作。
  1. 矩阵相乘的时间复杂度 参考

如果用朴素的算法,mxn的矩阵和nxk的矩阵相乘的运算量是O(mnk),原因是,计算结果是一个mk矩阵,这说明至少需要进行mk次运算,而每次运算还要进行n次的求和运算(左边的每一行*右边的每一列)
当然,如果用并行计算的话,比如python里的tensor.dot函数替代for循环,时间复杂度会大大降低

  1. 什么是时间复杂度 参考

算法的时间复杂度实际上是一种度量,并不是真正意义上算法运行的时间。时间复杂度是算法需要执行基本运算的次数所处的等级。 时间复杂度只考虑了最高项的次数,因为问题规模足够大时其他项的贡献可以忽略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值