輸出二叉樹
題目:在一個(gè) m*n 的二維字符串?dāng)?shù)組中輸出二叉樹,并遵守以下規(guī)則:
行數(shù) m 應(yīng)當(dāng)?shù)扔诮o定二叉樹的高度。
列數(shù) n 應(yīng)當(dāng)總是奇數(shù)。
根節(jié)點(diǎn)的值(以字符串格式給出)應(yīng)當(dāng)放在可放置的第一行正中間。根節(jié)點(diǎn)所在的行與列會(huì)將剩余空間劃分為兩部分(左下部分和右下部分)。你應(yīng)該將左子樹輸出在左下部分,右子樹輸出在右下部分。左下和右下部分應(yīng)當(dāng)有相同的大小。即使一個(gè)子樹為空而另一個(gè)非空,你不需要為空的子樹輸出任何東西,但仍需要為另一個(gè)子樹留出足夠的空間。然而,如果兩個(gè)子樹都為空則不需要為它們留出任何空間。
每個(gè)未使用的空間應(yīng)包含一個(gè)空的字符串""。
使用相同的規(guī)則輸出子樹。

思路:這個(gè)題怎么說呢,首先層數(shù)和list的元素?cái)?shù)的關(guān)系:1-1 。2-3。3-7。4-15.就是上一個(gè)翻倍+1.翻倍就是左右,加1是中間。到這里思路還是很清楚的。然后先把二維數(shù)組列出來,往里一層一層填充元素得了。估計(jì)這個(gè)填充還要dfs。我去試試代碼。
這個(gè)題特別有意思。我寫個(gè)n個(gè)方法,以為低空略過,結(jié)果一次ac性能超過百分百。先貼代碼:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int d = 0;
public List<List<String>> printTree(TreeNode root) {
List<List<String>> res = new ArrayList<List<String>>();
dfs(0, root);
int len = 1;
for(int i = 1;i<d;i++) len = len*2 + 1;
for(int i = 0;i<d;i++){
List<String> list = new ArrayList<String>();
for(int j = 0;j<len;j++) list.add("");
res.add(list);
}
dfs(res, root, 0, len-1, 0);
return res;
}
public void dfs(List<List<String>> res,TreeNode root,int start,int end,int len) {
if(root != null) {
int mid = (start+end)>>1;//因?yàn)橄聵?biāo)從0開始。所以這里的結(jié)果正好是中間那個(gè)
res.get(len).set(mid, String.valueOf(root.val));
dfs(res, root.left, start, mid-1, len+1);
dfs(res, root.right, mid+1, end, len+1);
}
}
public void dfs(int temp,TreeNode root){
if(root.left == null && root.right == null) d = Math.max(d, temp+1);
if(root.left != null) dfs(temp+1, root.left);
if(root.right != null) dfs(temp+1,root.right);
}
}
大概的思路和預(yù)計(jì)的差不多,先獲取這個(gè)二維數(shù)組的長寬。把空串填進(jìn)去。然后再根據(jù)樹一個(gè)一個(gè)元素替換,這里用了兩次遞歸:一次是找樹的高度。一次是填充元素。這么多代碼我都快以為是我想錯(cuò)了,沒成想這個(gè)題目就是這樣的。剛剛看了下性能第一的代碼和我這個(gè)思路差不多,所以這個(gè)題就這樣了,下一題。
找到k個(gè)最接近的元素
題目:給定一個(gè)排序好的數(shù)組 arr ,兩個(gè)整數(shù) k 和 x ,從數(shù)組中找到最靠近 x(兩數(shù)之差最?。┑?k 個(gè)數(shù)。返回的結(jié)果必須要是按升序排好的。整數(shù) a 比整數(shù) b 更接近 x 需要滿足:|a - x| < |b - x| 或者|a - x| == |b - x| 且 a < b
示例 1:
輸入:arr = [1,2,3,4,5], k = 4, x = 3
輸出:[1,2,3,4]
示例 2:
輸入:arr = [1,2,3,4,5], k = 4, x = -1
輸出:[1,2,3,4]
提示:
1 <= k <= arr.length
1 <= arr.length <= 104
數(shù)組里的每個(gè)元素與 x 的絕對值不超過 104
思路:這個(gè)題怎么說呢,我個(gè)人感覺是分兩部分:1.找出這些數(shù)。2.這些數(shù)字升序排列。至于怎么找出這些數(shù)應(yīng)該是從給定數(shù)字往兩頭外擴(kuò)吧。比如demo中從3開始兩邊擴(kuò)充(3本身要入結(jié)果集):2.4值一樣,但是2小,所以2入結(jié)果集。再往下1,4中4絕對值小,所以4入結(jié)果集。再往下1,5絕對值一樣但是1小,1入結(jié)果集。這個(gè)時(shí)候結(jié)果集滿了,所以返回。。。思路很清楚,我去寫代碼了。
第一版本代碼出來了,雖然ac的但是性能有點(diǎn)問題,我先貼出來:
class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
int len = arr.length-1;
int idx = -1;
if(arr[0]>=x) {//最小的數(shù)都大于x
idx = 0;
}else if(arr[len]<=x) {//最大的小于x。
idx = len;
}else {
for(int i = 0;i<len;i++) {
if(arr[i] == x) {
idx = i;
break;
}else if(arr[i]<x && arr[i+1]>x) {//x沒落在正好的位置
idx = arr[i+1]-x<x-arr[i]?i+1:i;//返回距離比較近的那個(gè).相等返回小的
break;
}
}
}
List<Integer> res = new ArrayList<Integer>();
res.add(arr[idx]);//最接近的元素直接放進(jìn)去
//從idx開始雙指針往外找。
int left = idx;
int right = idx;
//結(jié)果集沒滿就繼續(xù)填充
while(res.size()<k) {
if(right==len) {//不能往后指了,只能往前走
res.add(arr[--left]);
}else if(left == 0){
res.add(arr[++right]);
}else {
//后面的絕對值小選擇后面的,否則選擇前面的
if((arr[right+1]-x)<(x-arr[left-1])) {
res.add(arr[++right]);
}else {
res.add(arr[--left]);
}
}
}
Collections.sort(res);
return res;
}
}
這個(gè)題怎么說呢,暫時(shí)優(yōu)化思路都莫得,我感覺寫的挺好的啊,我直接去看看性能第一的代碼吧:
class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
int left = 0, right = k - 1;
while (right + 1 < arr.length && (arr[right + 1] <= x
|| arr[right + 1] - x < x - arr[left])) {
left++;
right++;
}
List<Integer> result = new ArrayList<>();
for (int i = left; i <= right; i++) {
result.add(arr[i]);
}
return result;
}
}
為什么都想到雙指針了卻沒想到滑窗啊?。?!為什么可以這么菜!!心態(tài)崩了啊,反正這個(gè)性能第一的代碼就是一個(gè)滑窗。因?yàn)槭沁f增序列。所以符合條件的結(jié)果集一定是一串挨著的元素。重點(diǎn)是判斷出從哪里開始的連續(xù)數(shù)組中元素而已。
一看這個(gè)思路我就會(huì)了,但是自己就是琢磨不出來,哭了啊~最近刷題刷的心態(tài)爆炸,感覺刷了這么久還是沒什么進(jìn)步。做題靠直覺,思路純暴力。哎,下一題下一題。
買賣股票的最佳時(shí)機(jī)含手續(xù)費(fèi)
題目:給定一個(gè)整數(shù)數(shù)組 prices,其中第 i 個(gè)元素代表了第 i 天的股票價(jià)格 ;非負(fù)整數(shù) fee 代表了交易股票的手續(xù)費(fèi)用。你可以無限次地完成交易,但是你每筆交易都需要付手續(xù)費(fèi)。如果你已經(jīng)購買了一個(gè)股票,在賣出它之前你就不能再繼續(xù)購買股票了。返回獲得利潤的最大值。注意:這里的一筆交易指買入持有并賣出股票的整個(gè)過程,每筆交易你只需要為支付一次手續(xù)費(fèi)。
示例 1:
輸入: prices = [1, 3, 2, 8, 4, 9], fee = 2
輸出: 8
解釋: 能夠達(dá)到的最大利潤:
在此處買入 prices[0] = 1
在此處賣出 prices[3] = 8
在此處買入 prices[4] = 4
在此處賣出 prices[5] = 9
總利潤: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
注意:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.
思路:這個(gè)題我不記得我做沒做過了,是今天的每日一題。買賣股票這塊作為dp的經(jīng)典題目,我記得我當(dāng)年統(tǒng)一刷過啊。話不多說,說解題思路。首先這個(gè)手續(xù)費(fèi)只收一筆,所以我們可以設(shè)置為在買入的時(shí)候比實(shí)際價(jià)格貴fee元。其次有一個(gè)概念:峰值一定是賣出或者留手,不可能最貴的時(shí)候買入。當(dāng)然同理肯定是在谷值買入,不然不會(huì)買貴的不買便宜的。所以說這個(gè)題可以先把prices簡化成峰值谷值峰值谷值。然后上一次賣不賣和這一次買不買是dp關(guān)系。差不多思路就這樣,我再去結(jié)合題目試著寫代碼吧。
怎么說呢,ac倒是ac了,但是性能不咋地,而且最后也不是dp實(shí)現(xiàn)的。先貼代碼:
class Solution {
public int maxProfit(int[] prices, int fee) {
int res = 0;
if(prices.length <2) return 0;//不管是沒有元素還是只有一個(gè)元素都不買,0收益
//手續(xù)費(fèi)可以算成是買入的時(shí)候+fee元。
//有一個(gè)概念:峰值一定是賣出或者留手,不可能最貴的時(shí)候買入
//不可能非谷值買入。干嘛不買便宜的買貴的?
//所以說這個(gè)題可以先把prices簡化成峰值谷值峰值谷值。。
//因?yàn)橘I入加手續(xù)費(fèi),所以谷值直接+fee.第一個(gè)肯定是谷值
//所以說只要低價(jià)買入能賺就賣出就買
//因?yàn)橘I入要手續(xù)費(fèi),所以這個(gè)手續(xù)費(fèi)直接算到買入價(jià)格
int buy = prices[0]+fee;
for(int i = 1;i<prices.length;i++) {
if(buy>prices[i]+fee) {//挑便宜的買,所以要替換買入價(jià)格
buy = prices[i] + fee;
}else if (prices[i]>buy){//現(xiàn)在買入的比價(jià)格賣了就是賺的,所以賣
res += prices[i]-buy;//賺的錢增加了
//因?yàn)檫@個(gè)prices[i]是賣出價(jià)格。有比這個(gè)價(jià)格高的直接這個(gè)不買下一個(gè)賣
//所以這個(gè)不用+fee。當(dāng)然如果再遇到比這個(gè)便宜的會(huì)重新買入。
buy = prices[i];
}
}
return res;
}
}
這種題目的一個(gè)特點(diǎn):思路理順了做起來會(huì)簡單的多。我覺得只要給我時(shí)間dp也不是不能實(shí)現(xiàn),不過在寫的過程中靈機(jī)一動(dòng)發(fā)現(xiàn)這個(gè)其實(shí)不非要用dp。就是峰值谷值看了半天看出了規(guī)律:倒手掙錢就倒手。dp規(guī)律就是峰值谷值/下一次谷峰差值加上當(dāng)前的大就檔次轉(zhuǎn)手再買再賣。否則一直留股到下次一起賣。我再去試試dp實(shí)現(xiàn):
class Solution {
public int maxProfit(int[] prices, int fee) {
int res = 0;
if(prices.length <2) return 0;//不管是沒有元素還是只有一個(gè)元素都不買,0收益
int buy = -prices[0];//記錄前一天的狀態(tài),手里持股
int sell = 0;//前一天的狀態(tài),手里不持股
for(int i = 1;i<prices.length;i++) {
//這一天的狀態(tài)是手里持股,那么就在前一天的基礎(chǔ)上買股,要么就是不買股
buy = Math.max(buy, sell-prices[i]);
//這一天的狀態(tài)是手里不持股的話,前一天沒股和前一天持股但是賣掉哪個(gè)合適
sell = Math.max(sell, buy+prices[i]-fee);
}
//最終一定是不持股的狀態(tài)
return sell;
}
}
真的有時(shí)候一開始思路有問題很難中途轉(zhuǎn)過來。dp本身和峰值谷值莫得關(guān)系。只要判斷當(dāng)前的最優(yōu)解就行了。每一天分兩種狀態(tài):當(dāng)前手里有股票,當(dāng)前手里沒股票。
我們只需要選擇每一天都是最優(yōu)解就行了。 手里不持股買當(dāng)天的和手里持以前的股,哪個(gè)賺的更多選擇哪個(gè)。同理當(dāng)天賣股票還是前一天賣股票哪個(gè)更賺錢就選擇哪個(gè)。
我剛剛看了下題解,這個(gè)可以用二維dp數(shù)組來實(shí)現(xiàn)。不過因?yàn)檫@個(gè)題只和上一天的狀態(tài)有關(guān),所以不用數(shù)組,用變量保存上一天的狀態(tài)就行了。
反正完整版的代碼如下,這個(gè)題也就這樣了,下一題。
二叉樹最大寬度
題目:給定一個(gè)二叉樹,編寫一個(gè)函數(shù)來獲取這個(gè)樹的最大寬度。樹的寬度是所有層中的最大寬度。這個(gè)二叉樹與滿二叉樹(full binary tree)結(jié)構(gòu)相同,但一些節(jié)點(diǎn)為空。每一層的寬度被定義為兩個(gè)端點(diǎn)(該層最左和最右的非空節(jié)點(diǎn),兩端點(diǎn)間的null節(jié)點(diǎn)也計(jì)入長度)之間的長度。


思路:這個(gè)題怎么說呢,審題幾遍才看懂。我目前的想法就是遍歷。所有不是首個(gè)節(jié)點(diǎn)的非空節(jié)點(diǎn)用null填充。最終統(tǒng)計(jì)每一次的有效元素?cái)?shù)(首尾不是null的)。我大概會(huì)用0,1來表示吧,有個(gè)簡單的思路,我去實(shí)現(xiàn)下。
第一個(gè)版本的代碼超時(shí)了,雖然我自認(rèn)為邏輯沒錯(cuò):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int widthOfBinaryTree(TreeNode root) {
int res = 0;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while(!queue.isEmpty()) {
int start = -1;
int end = -1;
int size = queue.size();
for(int i = 0;i<size;i++) {
TreeNode temp = queue.poll();
if(temp!=null && start == -1) start = i;//第一個(gè)有值的元素要記錄
if(temp!=null) end = i;//最后一個(gè)有值的元素記錄
//當(dāng)前元素非空添加兩個(gè)子節(jié)點(diǎn)
if(temp != null) {
queue.add(temp.left);
queue.add(temp.right);
}else if(start != -1){//有了非空元素才需要占位
queue.add(null);
queue.add(null);
}
}
res = Math.max(res, end-start+1);
//這一層都沒有元素的了,說明樹遍歷完了
if(start == -1) return res;
}
return res;
}
}
當(dāng)然也可能是做了很多無用功。而且我看了測試案例,覺得可能這種每一個(gè)元素都列出來是有問題的,我去想想優(yōu)化思路。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int widthOfBinaryTree(TreeNode root) {
int res = 0;
LinkedList<TreeNode> queue = new LinkedList<>();
LinkedList<Integer> indexQueue = new LinkedList<>();
queue.add(root);
indexQueue.add(1);
while (!queue.isEmpty()) {
int left = indexQueue.peek();
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode poll = queue.poll();
Integer index = indexQueue.poll();
res = Math.max(res, index - left + 1);
if (poll.left != null) {
queue.add(poll.left);
indexQueue.add(index * 2);
}
if (poll.right != null) {
queue.add(poll.right);
indexQueue.add(index * 2 + 1);
}
}
}
return res;
}
}
這個(gè)題我自己優(yōu)化了三個(gè)版本才發(fā)現(xiàn),我沒必要一直想著剪枝(中間有一個(gè)版本end后面的刪除)。重點(diǎn)是這個(gè)null就沒必要占位。因?yàn)槠鋵?shí)根據(jù)父節(jié)點(diǎn)一層一層就能推導(dǎo)出當(dāng)前節(jié)點(diǎn)按照滿樹來講所在的位置、同樣能能推算出結(jié)束節(jié)點(diǎn)所在位置。這樣不用null占位也知道中間隔了多少個(gè)值。于是最終版代碼出現(xiàn)了,所有入隊(duì)列的元素都是非空的,省去了很多性能。同樣根據(jù)下標(biāo)的位置判斷最大差值。反正這個(gè)題的思路就這樣了,我去看看題解吧。
看了性能排行第一的代碼:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int widthOfBinaryTree(TreeNode root) {
if(root == null) {
return 0;
}
Deque<TreeNode> queue = new LinkedList<>();
// 根節(jié)點(diǎn)編號為 0
root.val = 0;
queue.add(root);
int sum;
int ans = 0;
while(!queue.isEmpty()) {
sum = queue.size();
// 隊(duì)頭和隊(duì)尾的編號值求差用來更新寬度
ans = Math.max(ans, queue.getLast().val - queue.getFirst().val + 1);
// 一次處理一層,進(jìn)入這個(gè)循環(huán)前隊(duì)列中是一層的所有非空節(jié)點(diǎn)
while(sum > 0) {
TreeNode temp = queue.remove();
// 子節(jié)點(diǎn)入隊(duì)前修改 val, val = 滿二叉樹中節(jié)點(diǎn)編號
if(temp.left != null) {
queue.add(temp.left);
temp.left.val = temp.val * 2 + 1;
}
if(temp.right != null) {
queue.add(temp.right);
temp.right.val = temp.val * 2 + 2;
}
sum--;
}
}
return ans;
}
}
先說一下這個(gè)題用的雙端隊(duì)列。我之前有想到這個(gè)數(shù)據(jù)結(jié)構(gòu)。但是沒用。以為影響不會(huì)很大。其次兩點(diǎn)就是用樹節(jié)點(diǎn)的值表示當(dāng)前所在位置。這個(gè)挺新穎的一個(gè)思路。相比于上面兩個(gè)隊(duì)列對應(yīng)的代碼這個(gè)可能更好計(jì)算一點(diǎn)吧。有時(shí)候不得不感慨大家長的是一個(gè)腦子么。。。這種代碼屬于看了能理解,自己想不出來的東西。這個(gè)題主要就是二叉樹位置的計(jì)算-樹的左節(jié)點(diǎn)位置是父節(jié)點(diǎn)位置2.右節(jié)點(diǎn)為止是父節(jié)點(diǎn)位置2+1。
只要知道這兩個(gè)公式這個(gè)題做還是能做出來的,下一題了。
優(yōu)美的排序2
題目:給定兩個(gè)整數(shù) n 和 k,你需要實(shí)現(xiàn)一個(gè)數(shù)組,這個(gè)數(shù)組包含從 1 到 n 的 n 個(gè)不同整數(shù),同時(shí)滿足以下條件:
- ① 如果這個(gè)數(shù)組是 [a1, a2, a3, ... , an] ,那么數(shù)組 [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] 中應(yīng)該有且僅有 k 個(gè)不同整數(shù);.
- ② 如果存在多種答案,你只需實(shí)現(xiàn)并返回其中任意一種.
示例 1:
輸入: n = 3, k = 1
輸出: [1, 2, 3]
解釋: [1, 2, 3] 包含 3 個(gè)范圍在 1-3 的不同整數(shù), 并且 [1, 1] 中有且僅有 1 個(gè)不同整數(shù) : 1
示例 2:
輸入: n = 3, k = 2
輸出: [1, 3, 2]
解釋: [1, 3, 2] 包含 3 個(gè)范圍在 1-3 的不同整數(shù), 并且 [2, 1] 中有且僅有 2 個(gè)不同整數(shù): 1 和 2
提示:
n 和 k 滿足條件 1 <= k < n <= 104.
思路:簡單說一下思路,感覺這個(gè)題應(yīng)該比上一道簡單的多。首先k=1就是順序或者倒敘排列就不說了。如果k = n-1那么穩(wěn)妥的首尾想插入。重點(diǎn)就是中間階段的k怎么實(shí)現(xiàn):因?yàn)榇_定是n個(gè)連續(xù)整數(shù)。所以想保證每一塊的差值一樣還是能做到的??刹豢梢赃@么做:前面插入,到k-1中值的時(shí)候順序開始排列。保持差額是1。感覺可行性還挺高的,我去實(shí)現(xiàn)下試試。
一次ac,性能也不錯(cuò),挺好的。思路就是我上面說的思路,兩邊插入,到達(dá)到的值就順序往下遞增或遞減就ok了。
class Solution {
public int[] constructArray(int n, int k) {
int[] res = new int[n];
int idx = 0;
int start = 1;
int end = n;
boolean flag = true;//下一個(gè)要插入元素。true代表start.false代表end
while(k-->0) {
if(flag) {
res[idx++] = start++;
}else {
res[idx++] = end--;
}
flag = !flag;
}
if(!flag) {//順序往下
while(start<=end) res[idx++] = start++;
}else {//倒敘往上
while(start<=end) res[idx++] = end--;
}
return res;
}
}
感覺我這個(gè)思路沒啥問題,而且我看了人家給定的答案,我懷疑也是這種做法,只不過人家從多少種不同開始遍歷,最后順序往后順延就行了。我去看看性能第一的代碼,不出意外就這么過了:
class Solution {
public int[] constructArray(int n, int k) {
int[] res=new int[n];
int numk=k+1,numt=1;
//下標(biāo)段[0,k]中,偶數(shù)填充[1、2、3...]
for(int i=0;i<=k;i+=2){
res[i]=numt++;
}
//下標(biāo)段[0,k]中,奇數(shù)下標(biāo)填充[k+1,k,k-1...]
for(int i=1;i<=k;i+=2){
res[i]=numk--;
}
//其余的部分順序填充
for(int i=k+1;i<n;i++){
res[i]=i+1;
}
return res;
}
}
精巧的代碼,我是用flag來填充大數(shù)小數(shù)。人家是奇偶數(shù)。這個(gè)題就這樣了。下一題。
最大交換
題目:給定一個(gè)非負(fù)整數(shù),你至多可以交換一次數(shù)字中的任意兩位。返回你能得到的最大值。
示例 1 :
輸入: 2736
輸出: 7236
解釋: 交換數(shù)字2和數(shù)字7。
示例 2 :
輸入: 9973
輸出: 9973
解釋: 不需要交換。
注意:
給定數(shù)字的范圍是 [0, 108]
思路:這個(gè)題就簡單了,首先不存在超時(shí)問題,其次非負(fù)整數(shù)不存在正負(fù)不同分兩種情況的問題,最后大概思路就是第一位不是最大換成最大的,第一位是最大往下判斷。如果這個(gè)數(shù)字已經(jīng)是降序排列了那么就原樣輸出、差不多就這個(gè)思路。我先去實(shí)現(xiàn)下看看。
直接貼代碼:
class Solution {
public int maximumSwap(int num) {
char[] arr = String.valueOf(num).toCharArray();
for(int i = 0;i<arr.length;i++ ) {
int idx = i;
char value = arr[i];
for(int j = i+1;j<arr.length;j++) {
if(arr[j]>=value && arr[i] != arr[j]) {
value = arr[j];
idx = j;
}
}
if(idx != i) {
char temp = arr[i];
arr[i] = value;
arr[idx] = temp;
return Integer.valueOf(new String(arr));
}
}
return num;
}
}
感覺這個(gè)題的難度可能就是細(xì)節(jié)處理比較繁瑣?反正中間有個(gè)細(xì)節(jié)我坑了兩次:首先如果非當(dāng)前元素,有大于當(dāng)前元素的多個(gè)相同元素,那么用較后的那個(gè)替換。所以這里判斷條件是大于等于。但是如果和當(dāng)前元素一樣是沒必要替換的,所以還要加arr[i]!=arr[j]。就這一點(diǎn)我一開始沒想到所以提交了兩次都是錯(cuò)誤。不過只要注意到還是很容易改的。整體而言這個(gè)題不難。
本篇筆記就記到這里,如果稍微幫到你了記得點(diǎn)個(gè)喜歡點(diǎn)個(gè)關(guān)注。也祝大家工作順順利利~!今日共勉語句:天道酬勤。