前段時間,小白經過日夜兼程,有了那麼一丟丟基礎,那麼咋們現在拿起武器來進行刷怪吧!
一、小怪篇
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;
}
}
}
今天就到此爲此,血槽已空,帶我去喝瓶血,回回血