数组和字符串的基础题目学习(EPI)
学习的速度有些慢,脑袋转动的频率有些不是很高。不过今天的效率我觉得还是可以,应该不能称效率吧,就是整个感觉不错,感觉自己补充了很多的知识。其实G家和F家败了之后不知道看看算法题对接下来的找工作帮助是否会很大,但是看算法题目也是提高解决问题能力的一种方式吧,锻炼思维。僵化的思维实在有些不能忍受。
另外今天更是遇到之前leetcode之中的一些题目,当时那个题目第一时间没有思路,想了良久有了思路,有种灵机一动的感觉,今天碰到的时候竟然没有回想起来,即使自己的灵机一闪也无法依赖。那种灵机一动的时候人的状态可能提升了,正常的状态没办法恢复到那个效果了-_-。也许不断提高自己的正常状态,或者增加灵机一动的几率,也许只有靠不断的锻炼和不断的温故而知新了~。废话这么多,直接进入正题吧,今天的题目当中还是有很多非常值得期待(百思不得其解)的题目。
1.荷兰国旗问题。朴素的解释就是只含有0,1,2的数组进行排序,要求时间复杂度O(n),空间复杂度O(1)。(Leetcode)
扩展问题:如果数组含有0,1,2,3四个数值进行排序又需要如何排序?
类似快速排序的partition,但是快排的partition过程关于相等的部分未进行处理。思路就是保持一个尾部其后方均大于partition元素,保持一个头部指针其前方均小于partition元素。中间自然就是等于partition的元素。
void sorted(int A[],int i) {
//quick sort partition is not right
int start = 0;
int end = Alen - 1;
int partition = A[i];
for(int i = start;i <= end;i++) {
if( A[i] == partition ) {
continue;
}
else if( A[i] > partition ) {
swap(A[i--],A[end--]);
}
else {
swap(A[i--],A[start++]);
}
}
}
关于扩展问题4个元素的排序,我的想法是首先利用第二个数利用上述的方法进行partition会得到一个相对有序的数组,但是end -- 数据结尾这部分未排序,包含后两个元素的乱序,重新在进行一下partition,即调用两次partition的过程应该可以完成任务。不知道是不是还有更好的思路,欢迎留言~
2.设计一个方法,读&写一个未初始化的数组可达到O(1)的时间复杂度,可以利用额外的O(n)的空间,如果读到未初始化的单元需要返回false。
这个题目在《编程珠玑》中也出现过,但是只是简单的描述下思路,没有理解这个解题的过程,趁这个时间了解到了这个解题过程,非常有技巧的一个方法。
首先想到的利用额外的数组标示是否初始化...但是却被额外的数组如何初始化困扰-_-。 好吧,自己确实想不出什么好办法。
解决方案额外引入O(2n)的空间和一个整型变量。 思路如下图所示~
初始化操作:t=0,需要O(1)的时间复杂度。辅助数组P,S均是未初始化。
判断A[i]是否初始化利用:P[i] < t && S[P[i]] == i ( 可以这么理解,如果第i个未初始化,则P[i]随机数。如果不在0-t之间,直接返回未初始化。如果刚好是0-t的随机数,但是S[P[i]] == i这个随机数又无法保证,所以这里就能得出未初始化的结论)
插入一个元素的时候将P[i]对应的地方写入t,S[t] = i,然后t++,就能一直保证上面的验证了~。
图例表示的首先插入7,然后插入2,然后插入1后的状态。
3.一个数组A,求满足i < j的情况下,max(A[j] - A[i]),时间复杂度O(n)。
扩展问题:求满足 i 0 < j 0 < i 1 < j 1 的情况下,max( A[j0] - A[i0] + A[j1] - A[i1] ),时间复杂度O(n)。
更复杂的扩展问题:如果将上面的问题,1,2,扩展至n又应该如何解题目?即 max(A[j0] - A[i0] + A[j1] - A[i1] + .... + A[jk-1] - A[ik-1])。如何解决该普适性的问题呢?
这些题目刚好对应leetcode中的 股票I II III三个问题,其中更复杂的扩展为普适性解法。
4.设计一个高效的求n-sum子集模0的问题。问题具体描述,给定一个数组A,数组A的长度为n,设计一个高效的方法求出数组中模n为0的子集。
题目意思比较理解,当时没有理解透彻,以为和leetcode中的2-sum On,3-sum On2,4-sum On3 是一个类型的问题。所以就没有仔细思考。
解题思路如下:预先处理数组A,计算出prefixsum[i]为从0-i的A数组的和,根据i可以从0-n-1的属性,一共有n个前缀和,模n的结果为0-n-1刚好也n个鸽子,如果n个鸽子放进n个笼子,只有两种结果,每个笼子都有鸽子或是一个笼子放进了至少两个鸽子,如果第一种情况,则模为0的结果直接返回。 如果是一个笼子至少放进了两个鸽子,则可知prefixsum[x] == prefixsum[y],且假设x < y,则x 至 y 这段的和为0,模为0的和返回即可。~
题目中还有鸽巢原理的意味。
5.设计一个求出数组A中最长连续递增子串的算法。
理解题意之后就是连续增长的子串,扫描一遍就可以得到了,保存一个最长的长度,和最长长度开始的位置,扫描完毕直接截取子串就可以了。
EPI中描述了一种稍微优化的方法,稍微优化是因为最快情况的时间复杂度依然是O(n),这样相比之前,常数时间内没有得到提高。而且平均时间复杂度不像快速排序那样容易分析,不过优化的思路还是很有技巧的。
假设遍历中的一个场景,遍历至数组A[i]得到A[i-1]>=A[i],依照之前暴力的方法,这里需要在A[i]的位置重新开始计算一个子数组。这里假设在A[i]之前已经找到一个最长长度为L的连续递增子串,此时可以直接从A[i+L]的位置向A[i]遍历,如果出现一次非递减的数对,可以直接将i的位置调整至这个非递减的位置。
6.题目描述有些长,看起来是一个非常像考查并查集的题目。
并查集数据结构如何实现呢?
7.题意没有理解透彻,所以先不更新上来。
8.利用字符串模拟高精度的大整数乘法。
算是一个比较基础的题目了,实现的时候注意细节,如果利用string的话因为每个char的上限是255,实现乘法的时候我一般利用的是vector<int>这样没有一个溢出的问题。
9.给出一个数组A,和一个针对数组A的置换,利用常数的空间复杂度完成该置换对数组A的操作。
非常数空间复杂度的计算非常容易,重新开辟一个数组A,针对每个置换的位置直接将A的元素放置在置换后的位置即可。
置换可以分为不同的环,不同的环进行一次置换的时候不需要空间复杂度。但是分环的过程呢?其实这个问题在O(1)进行置换的时候存在一个问题是无法知道停止条件,这里有一个特殊的小技巧,每次利用完一个置换元素置换之后,将其减去置换数组的长度,这样它就变成了负数,再遇到这个时你就能够了解到它已经被访问过了。事后再将这些元素还原即可。
10.利用常数空间复杂度求一个置换的逆。
思路和上面题目的技巧类似,
11.求排列的下一个排列,及实现next_permutation。
扩展问题:求n个数字排列的第k个排列。
扩展问题:求排列的前一个排列,及实现pre_permutation.
组合数学中的一个很常见的算法~
第一个扩展问题,可以首先利用dfs求取全排列的模板,统计到k的时候完成,但是这样效率比较低,所以可以利用实现存储好的阶乘表进行剪枝操作,不断的剪去无效的搜索。
12.针对字符串进行原地的循环移位。
进行3次reverse操作即可完成操作。
13.将一个正方形矩阵旋转90度操作。
a.首先最直观的思路就是单个元素单个元素的进行置换。一层一层的向里进行,代码有些类似矩形的螺旋输出算法。
b.可以进行两次反转完成旋转90度的操作。如下图:
数组和字符串的基础题目学习(EPI)的更多相关文章
- 二叉树的基础题目学习(EPI)
1.判断是个二叉树是不是平衡二叉树. 二叉树的定义都是利用递归的方法,所以二叉树有着天然的递归属性.所以一般情况下,递归解决二叉树问题中,递归解法比较简洁.平衡二叉树的定义是左子树和右子树均是平衡二叉 ...
- 堆的基础题目学习(EPI)
堆的应用范围也比较广泛,经常游走在各种面试题目之前,不论算法设计的题目还是海量数据处理的题目,经常能看到这种数据结构的身影.堆其实就是一个完全二叉树的结构,经常利用数组来实现.包含最大堆和最小堆两种. ...
- 链表的基础题目学习(EPI)
链表的题目总体来说细节比较多,因为链表的题目在操作链表的过程中本身有些复杂,所以如果链表作为编程题出现的时候,多数情况下题目本身的思路可能不是很复杂,不要把题目往复杂的方向去思考就好了~这里的链表只是 ...
- 小插曲之变量和字符串 - 零基础入门学习Python003
小插曲之变量和字符串 让编程改变世界 Change the world by program 变量 (此处只是省略N多细节,详细通过视频学习) 变量名就像我们现实社会的名字,把一个值赋值给一个名字时, ...
- Swift语法基础入门二(数组, 字典, 字符串)
Swift语法基础入门二(数组, 字典, 字符串) 数组(有序数据的集) *格式 : [] / Int / Array() let 不可变数组 var 可变数组 注意: 不需要改变集合的时候创建不可变 ...
- (译文)学习ES6非常棒的特性-字符串常量基础
字符串常量基础 在ES2015之前我们是这么拼接字符串的: var result = 10; var prefix = "the first double digit number I le ...
- 第二十九节:Java基础知识-类,多态,Object,数组和字符串
前言 Java基础知识-类,多态,Object,数组和字符串,回顾,继承,类的多态性,多态,向上转型和向下转型,Object,数组,多维数组,字符串,字符串比较. 回顾 类的定义格式: [类的修饰符] ...
- C++基础之字符数组和字符串
无意中发现了一个非常有意思的技术类型小品文系列,通过大牛指导菜鸟的方式,解说讲C++知识,有的非常基础却是开发中easy忽略的地方. [Elminster的专栏] http://blog.csdn.n ...
- C语言基础知识-数组和字符串
C语言基础知识-数组和字符串 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组概述 在程序设计中,为了方便处理数据把具有相同类型的若干变量按有序形式组织起来的方式我们称为数组 ...
随机推荐
- 带你玩转Eclipse项目转成AndroidStudio项目
随着Android对Eclipse开发工具的淘汰,越来越多的公司使用AndroidStudio进行相应的Android开发工作.如此,原来用Eclipse开发的项目,怎么导入到AndroidStudi ...
- jsTree 插件
html代码 <div id="jstree1"></div> js代码: <script src="__STATIC__/h5/js/jq ...
- Thinkphp5 Route用法
域名路由:domain 1.application/router.php 文件位置,吧一下代码放进去就可以了 use think\Route; Route::domain('app.tp5a.com' ...
- 详解ABBYY FineReader 12扫描亮度设置
很多刚接触ABBYY FineReader 12的小伙伴可能出现过这样一个问题:在扫描过程中会显示一条消息以提示更改亮度设置.这是因为你 FineReader扫描设置中亮度未正确设置.下面小编就给小伙 ...
- 【QT】Cannot find file: untitled.pro,项目路径不要包含中文。
Cannot find file: D:\文件及下载相关\文档\untitled\untitled.pro. 17:01:45: 进程"D:\Englishpath\QT5.9.3\5.9. ...
- C#操作共享文件夹
public class NetFileShare { public NetFileShare() { } public static bool connectState(string path) { ...
- Apache+php5
.下载回来的是解压文件,解压好放到要安装的位置.(我这里以D:\Acpache24为例) .打开Apache24\conf下httpd.conf 文件,用记事本打开即可. ()第37行ServerRo ...
- Jackson Gson Json.simple 比较
为公司做了小任务,需要用到Java Json库,Json库我几个月之前就用过,不过那时候是跟着项目来的,延续了项目的使用习惯直接用了jackson Json,而这次我觉得好好比较一下几个常见的Json ...
- 彻底关闭Google的安全搜索
在使用简体中文的情况下,访问Google总是会跳转到香港,这个时候的安全搜索是无法关闭的. 下面介绍一个最简单的方法,直接使用Google的中文界面:https://www.google.com/we ...
- 从Gallery中获取图片示例
一.MainActivity类 package com.example.gallerydemo; import android.net.Uri; import android.os.Bundle; i ...