日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《剑指offer》-- 把数组排成最小的数、丑数、二进制中1的个数、表示数值的字符串、替换空格

發(fā)布時間:2024/9/30 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《剑指offer》-- 把数组排成最小的数、丑数、二进制中1的个数、表示数值的字符串、替换空格 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、把數(shù)組排成最小的數(shù):

1、題目:

輸入一個正整數(shù)數(shù)組,把數(shù)組里所有數(shù)字拼接起來排成一個數(shù),打印能拼接出的所有數(shù)字中最小的一個。例如輸入數(shù)組{3,32,321},則打印出這三個數(shù)字能排成的最小數(shù)字為321323。

2、解題思路:

重寫Comparator的compare()方法。

3、代碼實現(xiàn):

public class Test23 {public static void main(String[] args) {int[] array = new int[]{6,2,4,41,5};PrintMinNumber(array);}//解題思路://通過比較器重寫compare方法public static String PrintMinNumber(int [] numbers) {ArrayList<Integer> list = new ArrayList<>();for(int i=0;i<numbers.length;i++){list.add(numbers[i]);}Collections.sort(list,new Comparator<Integer>(){@Overridepublic int compare(Integer o1, Integer o2) {String str1=o1+""+o2;String str2=o2+""+o1;return str1.compareTo(str2);}});StringBuilder builder = new StringBuilder();for(Integer num:list){builder.append(num);}System.out.println(builder.toString());return builder.toString();} }

?

?

二、丑數(shù):

1、題目:

把只包含質(zhì)因子2、3和5的數(shù)稱作丑數(shù)(Ugly Number)。例如6、8都是丑數(shù),但14不是,因為它包含質(zhì)因子7。 習(xí)慣上我們把1當(dāng)做是第一個丑數(shù)。求按從小到大的順序的第N個丑數(shù)。

2、解題思路:

參考牛客網(wǎng)的“事無巨細(xì),悉究本末”:https://www.nowcoder.com/questionTerminal/6aa9e04fc3794f68acf8778237ba065b

2.1 通俗易懂的解釋:

首先從丑數(shù)的定義我們知道,一個丑數(shù)的因子只有2,3,5,那么丑數(shù)p = 2 ^ x * 3 ^ y * 5 ^ z,換句話說一個丑數(shù)一定由另一個丑數(shù)乘以2或者乘以3或者乘以5得到,那么我們從1開始乘以2,3,5,就得到2,3,5三個丑數(shù),在從這三個丑數(shù)出發(fā)乘以2,3,5就得到4,6,10,6,9,15,10,15,25九個丑數(shù),我們發(fā)現(xiàn)這種方法會得到重復(fù)的丑數(shù),而且我們題目要求第N個丑數(shù),這樣的方法得到的丑數(shù)也是無序的。那么我們可以維護(hù)三個隊列:

(1)丑數(shù)數(shù)組: 1

乘以2的隊列:2

乘以3的隊列:3

乘以5的隊列:5

選擇三個隊列頭最小的數(shù)2加入丑數(shù)數(shù)組,同時將該最小的數(shù)乘以2,3,5放入三個隊列;

(2)丑數(shù)數(shù)組:1,2

乘以2的隊列:4

乘以3的隊列:3,6

乘以5的隊列:5,10

選擇三個隊列頭最小的數(shù)3加入丑數(shù)數(shù)組,同時將該最小的數(shù)乘以2,3,5放入三個隊列;

(3)丑數(shù)數(shù)組:1,2,3

乘以2的隊列:4,6

乘以3的隊列:6,9

乘以5的隊列:5,10,15

選擇三個隊列頭里最小的數(shù)4加入丑數(shù)數(shù)組,同時將該最小的數(shù)乘以2,3,5放入三個隊列;

(4)丑數(shù)數(shù)組:1,2,3,4

乘以2的隊列:6,8

乘以3的隊列:6,9,12

乘以5的隊列:5,10,15,20

選擇三個隊列頭里最小的數(shù)5加入丑數(shù)數(shù)組,同時將該最小的數(shù)乘以2,3,5放入三個隊列;

(5)丑數(shù)數(shù)組:1,2,3,4,5

乘以2的隊列:6,8,10,

乘以3的隊列:6,9,12,15

乘以5的隊列:10,15,20,25

選擇三個隊列頭里最小的數(shù)6加入丑數(shù)數(shù)組,但我們發(fā)現(xiàn),有兩個隊列頭都為6,所以我們彈出兩個隊列頭,同時將12,18,30放入三個隊列;

……………………

2.2 疑問:

2.2.1 為什么分三個隊列?

丑數(shù)數(shù)組里的數(shù)一定是有序的,因為我們是從丑數(shù)數(shù)組里的數(shù)乘以2,3,5選出的最小數(shù),一定比以前未乘以2,3,5大,同時對于三個隊列內(nèi)部,按先后順序乘以2,3,5分別放入,所以同一個隊列內(nèi)部也是有序的;

2.2.2 為什么比較三個隊列頭部最小的數(shù)放入丑數(shù)數(shù)組?

因為三個隊列是有序的,所以取出三個頭中最小的,等同于找到了三個隊列所有數(shù)中最小的。

2.3 實現(xiàn)思路:

我們沒有必要維護(hù)三個隊列,只需要記錄三個指針顯示到達(dá)哪一步;“|”表示指針,arr表示丑數(shù)數(shù)組;

(1)1

|2

|3

|5

目前指針指向0,0,0,隊列頭arr[0] * 2 = 2,? arr[0] * 3 = 3,? arr[0] * 5 = 5

(2)1 2

2 |4

|3 6

|5 10

目前指針指向1,0,0,隊列頭arr[1] * 2 = 4,? arr[0] * 3 = 3, arr[0] * 5 = 5

(3)1 2 3

2| 4 6

3 |6 9

|5 10 15

目前指針指向1,1,0,隊列頭arr[1] * 2 = 4,? arr[1] * 3 = 6, arr[0] * 5 = 5

………………

3、代碼實現(xiàn):

public class Test24 {//解題思路:創(chuàng)建三個隊列 https://www.nowcoder.com/ta/coding-interviewspublic int GetUglyNumber_Solution(int index) {if(index<7)return index;//創(chuàng)建三個隊列的頭指針,newNum代表的是選出的最小數(shù)int t2=0,t3=0,t5=0;int newNum=1;//創(chuàng)建一個數(shù)組,存放丑數(shù)ArrayList<Integer> list = new ArrayList<>();list.add(newNum);for(int i=1;i<index;i++){//選出三個隊列里面最小的數(shù) newNum=Math.min(list.get(t2)*2,Math.min(list.get(t3)*3,list.get(t5)*5));//這三個if有可能進(jìn)入一個或者多個,進(jìn)入多個是三個隊列頭最小的數(shù)有多個的情況if(newNum == list.get(t2)*2) t2++; if(newNum == list.get(t3)*3) t3++; if(newNum == list.get(t5)*5) t5++; list.add(newNum);}return newNum;} }

?

?

三、二進(jìn)制中1的個數(shù):

1、題目:

輸入一個整數(shù),輸出該數(shù)二進(jìn)制表示中1的個數(shù)。其中負(fù)數(shù)用補(bǔ)碼表示。

2、思路:

第一種:使用java內(nèi)置的的toBinaryString方法來實現(xiàn);

第二種:利用位運算符來實現(xiàn):

(1)將n與n-1做與運算,會把最右邊的1去掉。比如: 1100 & 1011 = 1000 ,即 12 & 11 = 8,再利用計算器count++計算出有多少個 1 即可。

(2)詳細(xì)說明:如果一個整數(shù)不為0,那么這個整數(shù)至少有一位是1。如果我們把這個整數(shù)減1,那么原來他的二進(jìn)制處在整數(shù)最右邊的1就會變?yōu)?,原來在1后面的所有的0都會變成1(如果最右邊的1后面還有0的話)。其余所有位將不會受到影響。
(3)舉個例子:一個二進(jìn)制數(shù)1100,從右邊數(shù)起第三位是處于最右邊的一個1。減去1后,第三位變成0,它后面的兩位0變成了1,而前面的1保持不變,因此得到的結(jié)果是1011。我們發(fā)現(xiàn)減1的結(jié)果是把最右邊的一個1開始的所有位都取反了。這個時候如果我們再把原來的整數(shù)和減去1之后的結(jié)果做與運算,從原來整數(shù)最右邊一個1那一位開始所有位都會變成0。如1100&1011=1000.也就是說,把一個整數(shù)減去1,再和原整數(shù)做與運算,會把該整數(shù)最右邊一個1變成0.那么一個整數(shù)的二進(jìn)制有多少個1,就可以進(jìn)行多少次這樣的操作。

3、代碼實現(xiàn):

//利用java內(nèi)置的toBinaryString方法來實現(xiàn):public static int NumberOf1(int n){int count = 0;String str=Integer.toBinaryString(n);for(int i=0;i<str.length();i++){if(str.charAt(i)=='1'){count++;}}return count;}//利用位運算符來實現(xiàn):public static int NumberOf2(int n){int count = 0;if(n==0)return count;if(n!=0){while(n!=0){count++;n=n&(n-1);}}return count;}

?

?

四、表示數(shù)值的字符串:

1、題目:

實現(xiàn)一個函數(shù)用來判斷字符串是否表示數(shù)值(包括整數(shù)和小數(shù))。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示數(shù)值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。

2、代碼實現(xiàn):

public class Test11 {private int index = 0;//第二種解法:劍指offer解法:public boolean isNumeric(char[] str){if(str.length<1){return false;}boolean flag = scanInteger(str);if(index<str.length && str[index]=='.'){index++;flag = scanUnsignedInteger(str) || flag;}if(index < str.length && (str[index] =='E' || str[index]=='e')){index++;flag = flag && scanInteger(str);}return flag && index == str.length;}private boolean scanInteger(char[] str){if(index<str.length && (str[index]=='+' || str[index]=='-') )index++;return scanUnsignedInteger(str);}private boolean scanUnsignedInteger(char[] str) {int start = index;while(index < str.length && str[index]>='0' && str[index] <='9')index++;return start<index;//是否存在整數(shù)}//第一種解法:正則表達(dá)式public boolean isNumeric1(char[] str) {String string = String.valueOf(str);return string.matches("[\\+\\-]?\\d*(\\.\\d+)?([eE][\\+\\-]?\\d+)?");}/*以下對正則進(jìn)行解釋:[\\+\\-]? -> 正或負(fù)符號出現(xiàn)與否\\d* -> 整數(shù)部分是否出現(xiàn),如-.34 或 +3.34均符合(\\.\\d+)? -> 如果出現(xiàn)小數(shù)點,那么小數(shù)點后面必須有數(shù)字;否則一起不出現(xiàn)([eE][\\+\\-]?\\d+)? -> 如果存在指數(shù)部分,那么e或E肯定出現(xiàn),+或-可以不出現(xiàn),緊接著必須跟著整數(shù);或者整個部分都不出現(xiàn)*/ }

?

?

四、替換空格:

1、題目描述:

請實現(xiàn)一個函數(shù),將一個字符串中的每個空格替換成“%20”。例如,當(dāng)字符串為We Are Happy.則經(jīng)過替換之后的字符串為We%20Are%20Happy。

2、解題思路:

第一種:從前往后替換,后面的字符要不斷往后移動,要多次移動,所以效率低下;

第二種:從后往前,先計算需要多少空間,然后從后往前移動,則每個字符只為移動一次,這樣效率更高一點。

3、代碼實現(xiàn):

public String replaceSpace(StringBuffer str) {int spaceNum = 0;//原字符串中空格的個數(shù)for(int i = 0;i<str.length();i++){if(str.charAt(i)==' '){spaceNum++;}}int indexOld = str.length()-1;//indexOld為為替換前的str下標(biāo)int newLength = str.length() + spaceNum*2;//計算空格轉(zhuǎn)換成%20之后的str長度int indexNew = newLength -1;//indexNew為為把空格替換為%20后的str下標(biāo)str.setLength(newLength);;//使str的長度擴(kuò)大到轉(zhuǎn)換成%20之后的長度,防止下標(biāo)越界for(;indexOld>=0 && indexOld<indexNew;--indexOld){if(str.charAt(indexOld)==' '){str.setCharAt(indexNew--, '0');str.setCharAt(indexNew--, '2');str.setCharAt(indexNew--, '%');}else{str.setCharAt(indexNew--, str.charAt(indexOld));}}return str.toString();} }

?

?

總結(jié)

以上是生活随笔為你收集整理的《剑指offer》-- 把数组排成最小的数、丑数、二进制中1的个数、表示数值的字符串、替换空格的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。