為自己加更!明天周末,為了能放下心玩一天,今天要額外刷三道題!
Excel表列名稱
題目:給定一個正整數(shù),返回它在 Excel 表中相對應(yīng)的列名稱。例如,
1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB
...
示例 1:
輸入: 1
輸出: "A"
示例 2:
輸入: 28
輸出: "AB"
示例 3:
輸入: 701
輸出: "ZY"
怎么說呢,這道題屬于解是肯定能解出來,就是優(yōu)雅不優(yōu)雅的問題。我發(fā)現(xiàn)現(xiàn)在做題真的如果不考慮代碼的性能之類的問題,單純求解還是很簡單的。閑話少敘,說思路:我覺得這道題就是很單純的找規(guī)律的問題?,F(xiàn)在去仔細(xì)看看規(guī)律,一會兒回來再說
大行打臉現(xiàn)場再次出現(xiàn),這道題,我做了一個多小時,沒做出來。對,我才說過很簡單的,結(jié)果卡殼了。重新理一下思路。這可以看作是一個26進(jìn)制的問題。然后A代表1,B代表2,Z代表26。但是有個問題,就是遇到26的倍數(shù),是不進(jìn)位的,而只是AZ,BZ這樣表示。這就很煩躁。說26進(jìn)制不26,說27進(jìn)制也莫得27。我一直就是卡在這里了,遞歸,while循環(huán),for循環(huán)都判斷了。不行。除非判斷是不是一個被26整除的數(shù)。如果是則怎么怎么樣。這樣還涉及到一個多位問題。之前看題目我以為只是1-702之間呢,結(jié)果一提交發(fā)現(xiàn)可以好多位,然后推翻重寫。最后決定把這個特殊情況提出來單獨判斷。結(jié)果判斷來判斷去把自己判斷蒙了,所以決定出絕招:看大佬思路!
大佬思路很簡單,說26進(jìn)制就是26進(jìn)制。Z不聽話怎么辦?盤它唄!不開玩笑了,就是完全把A-Z的意義改變。A表示0.B表示1.C表示2....Z表示25.這樣就是一個很成熟的26進(jìn)制了。如果理解不了可以想想10進(jìn)制,從0開始到9。10這個數(shù)字是沒有的!
然后既然26進(jìn)制完善了,接下來完全可以按照進(jìn)制的方法來做了。不過要注意一點,實際上代表的數(shù)字比咱們進(jìn)制代表的數(shù)值是大1的(回憶一下,題目中A是1.B是2,,,Z是26).所以在每一步用進(jìn)制換算的時候是要把這個1減去的。只要這個能明白,這個題做起來真三行代碼。
上代碼:
class Solution {
public String convertToTitle(int n) {
StringBuilder sb = new StringBuilder();
while(n>0){
//注意這個一定要先-1再取余數(shù),不然先取余再-1會出現(xiàn)莫名其妙的問題。比如都取余0了,再減1.不用我說了吧?
n--;
//這里是個巧妙的算法。數(shù)字加上字符'A'.再轉(zhuǎn)化成char。
//'A'本來就是數(shù)字,'B'比'A'大1。如果是1+'A'結(jié)果轉(zhuǎn)成char就是'B'。以此類推。很容易理解。
sb.append((char)(n%26+'A'));
n=n/26;
}
return sb.reverse().toString();
}
}
再一次對思路感覺驚奇,日常一嘆吧。真的有時候就差那么一個思路。有了,豁然開朗。沒有怎么也想不出來。然后再次感謝leetCode里提供思路的大佬,好人一生平安吧~繼續(xù)下一題。
多數(shù)元素
給定一個大小為 n 的數(shù)組,找到其中的多數(shù)元素。多數(shù)元素是指在數(shù)組中出現(xiàn)次數(shù)大于 ? n/2 ? 的元素。你可以假設(shè)數(shù)組是非空的,并且給定的數(shù)組總是存在多數(shù)元素。
示例 1:
輸入: [3,2,3]
輸出: 3
示例 2:
輸入: [2,2,1,1,1,2,2]
輸出: 2
思路:一點也不夸張的說,不考慮性能問題分分鐘做出這道題(我要找回上道題被打的臉)!但是說一點不考慮性能就有點過分了。反正我一下好幾個思路。比如存map,值是key,次數(shù)是val,累加的。什么時候某個val大于n/2說明那個就是多數(shù)元素。還有把數(shù)組轉(zhuǎn)成list然后排序。因為確定多數(shù)肯定一半以上。直接獲取中間的元素看是什么那么多數(shù)元素就是什么。然后我要去擼代碼測性能啦!
回來了,用我簡單粗暴的方法做完了,性能比我想得好得多:
class Solution {
public int majorityElement(int[] nums) {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i:nums){
if(map.containsKey(i)){
if(map.get(i)+1>=nums.length/2+1){
return i;
}else{
map.put(i,map.get(i)+1);
}
}else{
map.put(i,1);
}
}
//在只要一個元素的情況下會直接走到這
return nums[0];
}
}

第二種想法也寫出來了:
class Solution {
public int majorityElement(int[] nums) {
//轉(zhuǎn)化成集合
List<Integer> list = Arrays.stream(nums).boxed().collect(Collectors.toList());
//排序
Collections.sort(list);
//返回中間位數(shù)的元素
return list.get(list.size()/2);
}
}
然后兩種方法速度都很感人。我要想想怎么優(yōu)化了。
另外一個小題外話:原來Leetcode是用jdk8運行的。因為我用java 9的方法報錯沒有這個方法。就是下面這個List.of();

好了,題外話說完了,我要開始研究這個題的最優(yōu)性能的解了:
我要鄭重認(rèn)個錯??!我發(fā)現(xiàn)數(shù)組能直接排序的,所以我上個方法中先轉(zhuǎn)list再排序純粹因為知識面窄,會的方法少。
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
//返回中間位數(shù)的元素
return nums[nums.length/2];
}
}
這個是排序取中位數(shù)的解。雖然我還沒看解析,但是我大概猜測這道題可能是想考數(shù)組的快排之類的?因為我現(xiàn)在直接數(shù)組排序取中位數(shù)運行速度是3ms,想要時間更短我覺得應(yīng)該就是不要用現(xiàn)成的api?好了,墨跡完畢,我去看解析了。

你看我就猜到了,直接用api肯定是不被推薦的,哎,還好我還有一個map計數(shù)法。順便我又順著大佬的思路解答了一次:
從第一個數(shù)開始count=1,遇到相同的就加1,遇到不同的就減1,減到0就重新?lián)Q個數(shù)開始計數(shù),總能找到最多的那個,下面是代碼:
class Solution {
public int majorityElement(int[] nums) {
int result = nums[0];
int count = 0;
for(int i : nums){
if(i==result || count==0){
result =i;
count++;
}else{
count--;
}
}
return result;
}
}
Excel表序列號
題目:給定一個Excel表格中的列名稱,返回其相應(yīng)的列序號。例如,
A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28
...
示例 1:
輸入: "A"
輸出: 1
示例 2:
輸入: "AB"
輸出: 28
示例 3:
輸入: "ZY"
輸出: 701
思路:這個題怎么說呢。撩個狠話吧,今天做不出來我就轉(zhuǎn)行!跟第一個題是一樣的。只不過第一題是十進(jìn)制轉(zhuǎn)化二十六進(jìn)制,這個題是二十六進(jìn)制轉(zhuǎn)化成10進(jìn)制。傻瓜式還原操作。我去直接擼代碼了。
做完回來了,半小時左右完成的,性能不好也不壞,反正能對付用。感覺這兩道題做完對進(jìn)制有了一個新的理解了。
其實只要上面第一題會了這個題就是一個逆推的過程。然偶就這樣吧。
class Solution {
public int titleToNumber(String s) {
//結(jié)果
int result = 0;
//用來存每一個位數(shù)的十進(jìn)制數(shù)字。
int n = 0;
for(int i =0;i<s.length();i++){
//因為26進(jìn)制是0-25.而實際上是1-26.所以這里要+1.減去'A'的技巧就不多說了。
n = s.charAt(i)-'A'+1;
//這個是每個數(shù)位上的數(shù) 乘 26(數(shù)位次方-1).Math.pow(m,n)結(jié)果是m的n次方。
//理解不了就替換成十進(jìn)制想
result += n * Math.pow(26,s.length()-1-i);
}
return result;
}
}
因為這個性能還不是最優(yōu)我還是去看看大神的思路。
哎,人生啊~就是一個不斷受打擊再站起來的過程。
我以為的不好不壞,其實就是對付而已。大神思路:
public int titleToNumber(String s) {
int result = 0;
for(int i =0;i<s.length();i++){
result = result*26 + s.charAt(i)-'A'+1;
}
return result;
}
準(zhǔn)確來講算上括號五號代碼。只能自然不如。
今天就到這了,順便回憶回憶最近刷了四十多題,雖說都是算法題但是也對一些基礎(chǔ)的api有了很大的了解和重新認(rèn)識,同時對思路的擴(kuò)展也有一定的作用(雖然離大神還遠(yuǎn))。如果寫的這些筆記或者說我自己思路的記錄稍微幫到了你,記得點個喜歡點個關(guān)注呦!順便祝大家也工作順順利利!周末愉快!