leetcode刷題記錄(949、367、374)
阿新 • • 發佈:2018-12-26
2018.12.25 leetcode 刷題總結
題號:949
給定一個由 4 位數字組成的陣列,返回可以設定的符合 24 小時制的最大時間。
最小的 24 小時制時間是 00:00,而最大的是 23:59。從 00:00 (午夜)開始算起,過得越久,時間越大。
以長度為 5 的字串返回答案。如果不能確定有效時間,則返回空字串。
示例 1:
輸入:[1,2,3,4]
輸出:“23:41”
示例 2:
輸入:[5,5,5,5]
輸出:""
提示:
A.length == 4
0 <= A[i] <= 9
我的想法:
- 獲得所有合法的小時組合,並記錄它們在陣列中的位置
- 遍歷所有合法的小時數,獲得相應小時數最大的合法的分鐘數,即陣列中去除組合成小時數的兩個數去組成最大的合法的分鐘數
- 在遍歷的時候找出最大的合法的小時數+分鐘數的組合
- 所有數字的不滿足的結果或初始值都會被賦成 -1
對應程式:
// java
class Solution {
public String largestTimeFromDigits(int[] A) {
// 獲得所有合法的小時組合
// hourMap<小時數,List<組成小時數的兩個數字的下標>>
Map<Integer, List<Integer> > hourMap = hourCombo(A);
// 若不存在,返回空
if(hourMap.size() == 0) {
return "";
}
// 記錄最大的小時數
int maxHour = -1;
// 記錄同小時數相對應的分鐘數
int maxMin = -1;
// 遍歷所有合法的小時數
for(Integer hour : hourMap.keySet()) {
List<Integer> list = hourMap.get(hour);
// 獲得與小時數相對應的分鐘數
int minute = maxMinute (A, list);
// 若無合法的分鐘數,跳到下一個小時數
if(minute == -1) {
continue;
}else {
// 找出最大的組合
// 注意,能進到這個else中說明小時+分鐘的組合都是合法的,
// 因此,找出小時數最大的就是組合後時間最大的
if(hour > maxHour) {
maxHour = hour;
maxMin = minute;
}
}
}
// 若不存在,返回空
if(maxHour == -1 || maxMin == -1) {
return "";
}
// 轉換格式,將一位數的數字前面加0
String hourStr = String.valueOf(maxHour);
if(maxHour < 10) {
hourStr = "0" + hourStr;
}
String minuteStr = String.valueOf(maxMin);
if(maxMin < 10) {
minuteStr = "0" + minuteStr;
}
// 返回 小時:分鐘
return hourStr + ":" + minuteStr;
}
// 獲得最大的合法的分鐘數
// @param A:所給陣列
// @param list:組成小時數的兩個數的下標
private int maxMinute(int[] A, List<Integer> list) {
boolean flag = true;
int a = -1;
int b = -1;
// 拿到陣列中其餘兩個數,分別賦給a,b
for(int i = 0 ;i < A.length; ++i) {
if(i == list.get(0) || i == list.get(1)) {
continue;
}
if(flag) {
a = A[i];
flag = false;
}else {
b = A[i];
}
}
// 得到所有的分鐘數(2種)
int ab = a * 10 + b;
int ba = b * 10 + a;
// 找出在[0,59]中最大的一個數並返回,不存在返回-1
int result = -1;
if(ab >= 0 && ab <= 59) {
if(ab > result) {
result = ab;
}
}
if(ba >= 0 && ba <= 59) {
if(ba > result) {
result = ba;
}
}
return result;
}
// 獲得所有合法的小時數的組合,並記錄他們的下標位置
private Map<Integer, List<Integer>> hourCombo(int[] A) {
Map<Integer, List<Integer>> map = new HashMap<>();
List<Integer> list = null;
for(int i = 0; i < A.length; ++i) {
for(int j = 0; j < A.length; ++j) {
// 不能和自己做小時數
if(j == i) {
continue;
}
// 計算所有可能的小時數
int num = A[i] * 10 + A[j];
// 將小時數限制在[0,23]之間
if(num >= 0 && num <= 23) {
list = new ArrayList<>();
// 記錄下標
list.add(i);
list.add(j);
// 新增結果
map.put(num, list);
}
}
}
return map;
}
}
題號:367
給定一個正整數 num,編寫一個函式,如果 num 是一個完全平方數,則返回 True,否則返回 False。
說明:不要使用任何內建的庫函式,如 sqrt。
示例 1:
輸入:16
輸出:True
示例 2:
輸入:14
輸出:False
我的想法:
n的完全平方等於n項由1開始的奇數的和
e.g. 16 = 1 + 3 + 5 + 7
對應程式:
// java
class Solution {
public boolean isPerfectSquare(int num) {
int flag = 1;
while(num > 0) {
num -= flag;
flag += 2;
if(num == 0) {
return true;
}
}
return false;
}
}
這個辦法在所給數字非常大的時候會費時,提交記錄中執行用時0ms的解答中用的是一種縮小區間逐漸逼近答案的辦法,類似二分查詢法
程式:
// java
class Solution {
public boolean isPerfectSquare(int num) {
long temp=num/2+1;
long start=0;
long end=temp;
while(start<=end){
long mid=start+(end-start)/2;
long result=mid*mid;
if(result==num)
return true;
else if(result<num)
start=mid+1;
else
end=mid-1;
}
return false;
}
}
上面的程式中,初始區間選在[0,n/2+1]之間,可以保證任何數的平方根都落在此區間,因為 (n/2+1)2 - n = n2/4 + 1 一定是大於零的。
題號:374
我們正在玩一個猜數字遊戲。 遊戲規則如下:
我從 1 到 n 選擇一個數字。 你需要猜我選擇了哪個數字。
每次你猜錯了,我會告訴你這個數字是大了還是小了。
你呼叫一個預先定義好的介面 guess(int num),它會返回 3 個可能的結果(-1,1 或 0):
-1 : 我的數字比較小
1 : 我的數字比較大
0 : 恭喜!你猜對了
示例 :
輸入: n = 10, pick = 6
輸出: 6
我的想法:
二分查詢,縮小查詢區間,遞迴呼叫guess()函式
對應程式:
// java
/* The guess API is defined in the parent class GuessGame.
@param num, your guess
@return -1 if my number is lower, 1 if my number is higher, otherwise return 0
int guess(int num); */
public class Solution extends GuessGame {
public int guessNumber(int n) {
return guessNumber(1, n);
}
// @param start:區間左端點
// @param end: 區間右端點
private int guessNumber(int start, int end) {
// 二分查詢,標誌位數字
// 不要直接寫成(start + end)/ 2,防止溢位
int temp = start + (end - start)/2;
// 得到查詢結果標誌
int guessFlag = guess(temp);
if(guessFlag == 0) {
// 遞迴出口
return temp;
}else if(guessFlag < 0) {
// 區間向左縮小
return guessNumber(start, temp-1);
}else {
// 區間向右縮小
return guessNumber(temp+1, end);
}
}
}