前段时间,小白经过日夜兼程,有了那么一丢丢基础,那么咋们现在拿起武器来进行刷怪吧!
一、小怪篇
1.矩阵不仅是表示多维数组,而且是表示图的重要工具,这样的说法正确吗?
这样的说话正确;图的表示方法有两种,分别是邻接矩阵和邻接表;
2.优化的起泡排序的排序趟数与参加排序的序列原始状态有关()
肯定的,优化过的气泡排序与序列有关,最初的与序列无关
3.对待排序的元素序列进行划分,将其分为左、右两个子序列,再对两个子序列施加同样的排序操作,直到子序列为空或只剩一个元素为止。这样的排序方法是 __快速排序__。
快排思想:第一次排序,根据选取的枢纽元将序列分为两部分,枢纽元左边的A部分都比枢纽元小,枢纽元右边的B部分都比枢纽元大再分别对AB两部分进行枢纽元选取和划分
快速排序的思想就是分治法。
4.内部排序方法的稳定性是指该排序算法不允许有相同的关键字记录。错误
排序方法的稳定性是指在排序过程中是否改变相同元素的相对位置,若不变则稳定,否则不稳定。
举个例子:
稳定:如果 a
原本在 b
前面,而 a = b
,排序之后 a
仍然在 b
的前面;
不稳定:如果 a
原本在 b
的前面,而 a = b
,排序之后 a
可能会出现在 b
的后面;
5.若串S=′software′,其子串的数目是() 37
刚开始,我填的是9
字串(包含空串): n(n+1)/2 + 1
非空子串:n(n+1)/2
非空真子串(不包括空串和跟自己一样的子串):n(n+1)/2 - 1
6.输入若已经是排好序的,下列排序算法最快的是(插入排序)
咋们来看一看解释:
A:插入排序只需要遍历一遍,时间复杂度为O(n)
B:希尔排序基于插入排序,只有好的情况下才能达到O(n),他是基于插入排序的
C:归并排序时间复杂度为nlogn
D:快速排序在排好序的情况下,时间复杂度为n^2
7.串中任意个字符组成的子序列称为该串的子串。 错误
首先,你得知道子串的定义,串中任意个连续的 字符 组成的子序列 注意:是连续的,连续的
8.
下面描述中正确的为:
A.线性表的逻辑顺序与物理顺序总是一致的。
B.线性表的顺序存储表示优于链式存储表示。
C.线性表若采用链式存储表示时所有结点之间的存储单元地址可连续可不连续。
D.二维数组是其数组元素为线性表的线性表。
A:顺序存储结构中,线性表的逻辑顺序和物理顺序总是一致的。但在链式存储结构中,线性表的逻辑顺序和物理顺序一般是不同的。
B:各种存储结构都有其优缺点,线性表的顺序存储表示在快速查找方面具有一定优势,但链式存储表示在数据元素的插入和删除方面具有明显优势。
C: 链式存储可以连续,可以不连续,存储时不管其连续还是不连续,都是用指针指向下一个结点
D:线性表的数据元素是不可再分割的数据单元,因此数组不能作为线性表的结点
9.以下排序算法中,最坏情况时间复杂度与其他选项不同的是()
A.冒泡排序
B.快速排序
C.插入排序
D.归并排序
来一张图,足以说明,来,上图
10.外部排序是把外存文件调入内存,可利用内部排序的方法进行排序,因此排序所花的时间取决于内部排序的时间() 对
外部排序的总时间 = 内部排序(产出初始归并段)所需时间 + 外存信息读取时间 + 内部归并所需的时间
也可以说是就是内存放不下, 才要外排的。 中间会涉及很多写文件的操作
11.用一维数组存储二叉树时,总是以前序遍历顺序存储结点() 错
总是以层次遍历的顺序存储,并且按照完全二叉树的方式建立,所以有很多空节点,会浪费存储空间,完全二叉树可以非常方便地找到孩子兄弟和双亲;
12.排序算法分为稳定和不稳定的。通俗地讲,稳定排序就是能保证排序前两个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。在快速排序、冒泡排序、堆排序、归并排序、插入排序这五种排序算法中,属于稳定排序的有几个?3个
不稳定的有快速,希尔,堆,选择
13.
若对序列(2,12,16,70,5,10)按值从小到达进行排序,前三趟排序的结果分别为:
第1趟排序的结果为:(2,12,16,5,10,70),
第2趟排序的结果为:(2,12,5,10,16,70),
第3趟排序的结果为:(2,5,10,12,16,70),
由此可以断定,该排序过程采用的排序方法是(冒泡排序 )。
选项A插入排序的原理:在有序序列插入一个元素,保持序列有序。第二趟5应该插入到2之后。所以不符合。
选项B选择排序的原理:在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;第二趟应该选出5放在第二个位置,所以排序不符合。
选项C冒泡排序:相邻元素比较交换。
选项D快速排序的原理:选一个基准,其左边的元素都小于或等于它,其右边的元素都大于它,分成两段,直至每段仅有一个元素。根据选项给出的第一趟排序不符合。
14.下列排序算法中,某一趟结束后未必能选出一个元素放在其最终位置上的是(直接插入排序)。
A:堆排序每趟总能选出一个最大值或者最小值位于根节点。
B:冒泡排序总是两两比较选出一个最小值位于数组前面。
C:快排选出的枢轴在一趟排序中就位于了它最终的位置
D:直接插入排序不一定会位于最终的位置,因为不确定后面插入的元素对于前面的元素是否产生影响。
15.京东商城plus会员的消费记录金额分别为900,512,613,700,810,若采用选择排序算法对其进行从小到大的排序,第三趟排序结果为:(C)
A.900512613700810
B.512900613700810
C.512613700900810
D.512613700810900
选择排序就是获取未排序部分数据中最小的数据放到数组的最前面,以此类推
开始时:900,512,613,700,810
第一趟后:512,900,613,700,810
第二趟后:512,613,900,700,810
第三趟后:512,613,700,900,810
16.以下哪种排序算法对[1, 3, 2, 4, 5, 6, 7, 8, 9]进行排序最快 A
A .改良的冒泡排序
B.快速排序
C.归并排序
D.堆排序
快速,归并,堆排序的时间复杂度是NlogN
改良的冒泡在序列基本有序的情况下,时间复杂度能达到O(n)
17.设栈的初始状态为空,当字符序列a3_作为栈的输入时,输出长度为3的且可以用作C语言标识符的字符串序列有(3)个。
A.4 B.6 C.3 D.5
首先,栈的顺序是先进后出
字符序列为a3_ 1)a入栈,再出栈,然后3入栈,再出栈,—入栈,再出栈 序列是a3_
2)a入栈,再出栈,然后3,—入栈,再出栈,序列是a_3
3)a入栈,3入栈,再出栈,a出栈, —入栈,再出栈 序列是3a_
4) a入栈,3入栈,再出栈, —入栈,序列是3_a
5) a入栈,3入栈,_入栈,序列是_3a
其次,C语言的标识符不能以数字开头,去除3a_和3_a 答案为3
还涉及一个卡特兰公式h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
18.以下程序段的运行结果是( "output" )。
char str[10] = "output";
printf("\"%s\"\n", str);
\n 换行
\r 回车
\f 换页符
\b 退格
\0 空格
\s 字符串
\t 制表符
\” 双引号
\’ 单引号
所以,他的输出就是"output"
19.下列排序法中,每经过一次元素的交换会产生新的逆序的是(A )
A.快速排序
B.冒泡排序
C.简单插入排序
D.简单选择排序
产生新的逆序对,并不是说逆序对的数目发生改变。稳定的排序算法,每交换一次,逆序对的数目必然发生改变。
冒泡每交换一次,会减少一个逆序对,并不会产生新的逆序对。
简单插入排序,若插入到已排序序列的最后,则不会产生新的逆序对。
简单选择排序,每次将一个元素归位。无论由小到大归位,还是由大到小归位,都不会产生新的逆序对。
而快排,是跳跃式交换,必然会产生新的逆序对。
20.二维数组k[1..7,1..9],每元素大小占2个字节,而且使用列存储,a[5,4]的偏移量为(50)个字节。
首先可以确定的是9行7列,问题中的a[5][4]指的是在第五列的第四个,这个地方大家可能误解了,还有就是二维数组转化成一维数组的公式a[x][y]=b[x*列数+y],其中的x,y的起始地址为0,不是1,所以这题应该减一,也就是a[4][3],3*7+4=25,再乘以2结果出来了。
偏移量= 起始地址 + (a[1][1] + a[2][1] +.... a[4][4]) * size=(7*3+4)*2=50
二、小Boss篇
1.给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
import java.util.Arrays;
class Solution66 {
public static void main(String[] args){
int[] digits={9,8,7,6,5,4,3,2,1,0};
System.out.println(Arrays.toString(plusOne(digits)));
}
public static int[] plusOne(int[] digits) {
int carry=1;
for(int i=digits.length-1;i>=0;i--){
int num=digits[i]+carry;
digits[i]=num%10;
carry=num/10;
if(carry==0){
break;
}
}
if(carry==1){ //只能说明数组当中肯定是全9
int[] arr=new int[digits.length+1];
arr[0]=1;
return arr;
}
return digits;
//错误的思路 整形溢出
/*
int num=0;
for(int i=0;i<digits.length;i++){
num=num*10+digits[i];
}
num=num+1;//124
int[] arr=new int[(""+num).length()];
for(int i=arr.length-1;i>=0;i--){
arr[i]=num%10;
num/=10;
}
return arr;
*/
}
}
2.
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [3,2,3]
输出: 3示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
class Solution169 {
public int majorityElement(int[] nums) {
//不使用排序 在O(n)解决
int m=nums[0];
int count=1;
for(int i=1;i<nums.length;i++){
if(nums[i]==m){
count++;
}else{
count--;
if(count==0){
m=nums[i];
count=1;
}
}
}
return m;
/*
Arrays.sort(nums); //O(n*logn)
return nums[nums.length/2];
*/
/*
Arrays.sort(nums);
int m=0;
int mcount=0;
for(int i=0;i<nums.length;){
if(i>nums.length/2){
break;
}
int count=1;
for(int j=i+1;j<nums.length;j++){
if(nums[j]==nums[i]){
count++;
}else{
break;
}
}
if(count>mcount){
mcount=count;
m=nums[i];
}
i+=count;
}
return m;
*/
}
}
3.
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
示例:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
class Solution209 {
public int minSubArrayLen(int s, int[] nums) {
int len=0;
int i=0;
int sum=0;
for(int j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=s){
len=len==0?(j-i+1):Math.min(len,j-i+1);
sum-=nums[i];
i++;
}
}
return len;
}
}
4.
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]说明: 必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
class Solution283 {
public void moveZeroes(int[] nums) {
int k=0;
int temp=0;
for(int i=0;i<nums.length;i++){
if(nums[i]!=0){
temp=nums[i];
nums[i]=nums[k];
nums[k]=temp;
k++;
}
}
}
5.给定一个未经排序的整数数组,找到最长且连续的的递增序列。
示例一:输入: [1,3,5,4,7]
输出: 3
解释: 最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在原数组里被4隔开。示例二:
输入: [2,2,2,2,2] 输出: 1 解释: 最长连续递增序列是 [2], 长度为1。
class Solution674 {
public static void main(String[] args){
int[] nums={2,2,2,2};
int len=findLengthOfLCIS(nums);
System.out.println(len);
}
public static int findLengthOfLCIS(int[] nums) {
if(nums.length==0||nums.length==1){
return nums.length;
}
int maxL=0;
int maxR=0;
int l=0;
int r=0;
int maxCount=1;
int count=1;
for(int i=0;i<nums.length-1;i++){
if(nums[i+1]>nums[i]){
count++;
r=i+1;
}else{
count=1;
l=i+1;
r=i+1;
}
if(count>maxCount){
maxCount=count;
maxL=l;
maxR=r;
}
}
System.out.println(maxL+"~"+maxR);
return maxCount;
}
}
6.
给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。
我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。
如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。
示例1:
输入:
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释:
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。示例2:输入: nums = [1, 2, 3] 输出: -1 解释: 数组中不存在满足此条件的中心索引
说明:
nums
的长度范围为[0, 10000]
。任何一个
nums[i]
将会是一个范围在[-1000, 1000]
的整数。
class Solution724 {
public int pivotIndex(int[] nums) {
int sum=0;
for(int num:nums){
sum+=num;
}
int leftSum=0;
int rightSum=0;
for(int i=0;i<nums.length;i++){
if(i==0){
leftSum=0;
}else{
leftSum+=nums[i-1];
}
rightSum=sum-nums[i]-leftSum;
if(rightSum==leftSum){
return i;
}
}
return -1;
}
}
7.
给定一个非负整数数组
A
,返回一个数组,在该数组中,A
的所有偶数元素之后跟着所有奇数元素。你可以返回满足此条件的任何数组作为答案。
示例:输入:[3,1,2,4]
输出:[2,4,3,1]
输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
提示:
1 <= A.length <= 5000
0 <= A[i] <= 5000
class Solution905 {
public int[] sortArrayByParity(int[] A) {
int left=0;
int right=A.length-1;
while(left<right){
if(A[left]%2==1&&A[right]%2==0){
int temp=A[left];
A[left]=A[right];
A[right]=temp;
}else if(A[left]%2==0&&A[right]%2==1){
left++;
right--;
}else if(A[left]%2==0&&A[right]%2==0){
left++;
}else{
right--;
}
}
return A;
}
}
8.将数组分成和相等的三个部分
给定一个整数数组 A,只有我们可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。
形式上,如果我们可以找出索引 i+1 < j 且满足 (A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1]) 就可以将数组三等分。
示例1:
输出:[0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1示例2:
输入:[0,2,1,-6,6,7,9,-1,2,0,1]
输出:false
示例3:
输入:[3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
class Solution1013 {
public boolean canThreePartsEqualSum(int[] A) {
int sum=0;
for(int num:A){
sum+=num;
}
int key=sum/3;
int group=0;
for(int i=0;i<A.length;i++){
key-=A[i];
if(key==0){
group++;
key=sum/3;
}
}
return group==3;
}
}
9.统计位数为偶数的数字
给你一个整数数组
nums
,请你返回其中位数为 偶数 的数字的个数。示例1:
输入:nums = [12,345,2,6,7896]
输出:2
解释:
12 是 2 位数字(位数为偶数)
345 是 3 位数字(位数为奇数)
2 是 1 位数字(位数为奇数)
6 是 1 位数字 位数为奇数)
7896 是 4 位数字(位数为偶数)
因此只有 12 和 7896 是位数为偶数的数字示例2:
输入:nums = [555,901,482,1771]
输出:1
解释: 只有 1771 是位数为偶数的数字。
提示:
1 <= nums.length <= 500
1 <= nums[i] <= 10^5
class Solution1295 {
public int findNumbers(int[] nums) {
int count=0;
for(int i=0;i<nums.length;i++){
if((nums[i]+"").length()%2==0){
count++;
}
}
return count;
}
}
10.解压缩编码列表
给你一个以行程长度编码压缩的整数列表 nums 。
考虑每对相邻的两个元素 [a, b] = [nums[2*i], nums[2*i+1]] (其中 i >= 0 ),每一对都表示解压后有 a 个值为 b 的元素。
请你返回解压后的列表。
示例:
输入:nums = [1,2,3,4]
输出:[2,4,4,4]
解释:第一对 [1,2] 代表着 2 的出现频次为 1,所以生成数组 [2]。
第二对 [3,4] 代表着 4 的出现频次为 3,所以生成数组 [4,4,4]。
最后将它们串联到一起 [2] + [4,4,4] = [2,4,4,4]。提示:
2 <= nums.length <= 100
nums.length % 2 == 0
1 <= nums[i] <= 100
class Solution1313 {
public int[] decompressRLElist(int[] nums) {
int len=0;
for(int i=0;i<nums.length;i+=2){
len+=nums[i];
}
int[] arr=new int[len];
int index=0;
for(int i=1;i<nums.length;i+=2){
for(int j=0;j<nums[i-1];j++){
arr[index++]=nums[i];
}
}
return arr;
}
}
11.两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
对于这道题,直接使用的暴力解法
class Solution {
public int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] == target - nums[i]) {
return new int[] { i, j };
}
}
}
throw new RuntimeException("No two sum solution");
}
}
12.两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
对于这道题,咋们得先判断是不是非空链表,如果两者都不是方可以相加
如果,其中有一组链表是空的,直接返回另一组的链表
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if(l2 == null) {
return l1;
}else if(l1 == null && l2 != null){
return l2;
}else {
l1.val = l1.val+l2.val;
jinwei(l1);
l1.next = addTwoNumbers(l1.next,l2.next);
return l1;
}
}
public void jinwei(ListNode l1) {
if(l1.val>9) {
if(l1.next == null){
l1.next = new ListNode(l1.val/10);
}else{
l1.next.val += l1.val/10;
jinwei(l1.next);
}
l1.val %= 10;
}
}
}
13.无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
首先,咋们得判断这个字符是否大于0,是否为空
class Solution {
public int lengthOfLongestSubstring(String s) {
//如果s为空,length不大于0,是一个空串,就没有向下执行的必要了
if(s != null && s.length() > 0 && s != ""){
//String -> char[]
char[] strChar = s.toCharArray();
// 存储最长字串 key:char值,value:index下标
ArrayList<String> maxStr = new ArrayList<>();
//临时的字串存储空间
ArrayList<String> tempStr = new ArrayList<>();
//循环
for(int i=0; i<strChar.length; i++){
//char -> String
String str = new String(new char[]{strChar[i]});
//判断str是否存在于tempStr中
if(tempStr.contains(str)){
//先判断tempStr的长度是否大于等于maxStr的长度,大于,才能将最长字串覆盖
if(tempStr.size() > maxStr.size()){
maxStr = new ArrayList<>(tempStr);
}
//存储重复字符
int reIndex = tempStr.indexOf(str);
// 删除tempStr中的重复字节及其之前的字符
for(int j=0;j<=reIndex;j++){
tempStr.remove(0);
}
}
//将当前字符存入tempStr中
tempStr.add(str);
}
//最终判断
if(tempStr.size() > maxStr.size()){
maxStr = tempStr;
}
//返回最长字串的长度
return maxStr.size();
}
return 0;
}
}
14.整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
class solution7{
public int reverse(int x) {
long rst=0;
while(x!=0){
rst= rst*10+ x%10;
x=x/10;
}
if((int)rst!=rst){
return 0;
}else{
return (int)rst;
}
}
}
今天就到此为此,血槽已空,带我去喝瓶血,回回血
来源:CSDN
作者:-丶南屿〃◇
链接:https://blog.csdn.net/qq_43667317/article/details/104451240