Leetcode演算法Java全解答--41. 缺失的第一個正數
阿新 • • 發佈:2018-12-10
Leetcode演算法Java全解答–41. 缺失的第一個正數
文章目錄
題目
給定一個未排序的整數陣列,找出其中沒有出現的最小的正整數。
說明:
你的演算法的時間複雜度應為O(n),並且只能使用常數級別的空間。
示例
示例 1: 輸入: [1,2,0] 輸出: 3 示例 2: 輸入: [3,4,-1,1] 輸出: 2 示例 3: 輸入: [7,8,9,11,12] 輸出: 1
想法
-
錯了!使用二進位制來儲存,將第N位的資料改成1,原來想的有二十億資料,後面發現int只有32位,只能保證32個,錯了
-
交換法
將1放到陣列 索引0位置,將2放到陣列 索引1的位置,將3放到陣列索引1的位置
假設交換的資料還是大於0且小於i+1,則放在合適的位置,且資料不相等,避免死迴圈
用的是 if判斷 加上 i–,別人的方法使用while迴圈
然後去迴圈陣列,資料不對就返回
結果
超過97%的測試案例
時間複雜度/空間複雜度:O(n)/1
總結
// TODO
程式碼
我的答案
public int firstMissingPositive(int[] nums) { if (nums.length == 0) { return 1; } for (int i = 0; i < nums.length; i++) { if (nums[i] > 0) { // 假設交換的資料還是大於0且<i+1,則放在合適的位置,且資料不相等,避免死迴圈 if (nums[i] < nums.length + 1 && nums[i] != nums[nums[i] - 1]) { int tmp = nums[nums[i] - 1]; nums[nums[i] - 1] = nums[i]; nums[i] = tmp; i--; } } } // 然後去迴圈陣列,資料不對就返回 for (int i = 0; i < nums.length; i++) { if (i + 1 != nums[i]) { return i + 1; } } return nums.length + 1; } /** * 位運算,錯誤答案 * @param nums * @return */ public int bit(int[] nums) { long bitNum = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] > 0) { // 將bitNum的第nums[i]變為1 // 第 i 位與0 或,值不變。第 i 位與1 或,變成1。因此,我們的目標是 num 與 一個第 i 位值為1,其它位的值都為0的數相 或 bitNum = bitNum | (1 << nums[i]); } } for (int i = 1; i < nums.length + 1; i++) { boolean zeroBit = (bitNum & (1 << i)) == 0; if (zeroBit) { return i; } } return nums.length + 1; }
大佬們的答案
/************************************** * 比我好的答案 better * ***********************************/ public int better(int[] nums) { int n = nums.length; for (int i = 0; i < n; i++) { while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) { int temp = nums[nums[i] - 1]; nums[nums[i] - 1] = nums[i]; nums[i] = temp; } } for (int i = 0; i < n; i++) { if (nums[i] != i + 1) { return i + 1; } } return n + 1; }
測試用例
@Test
public void test041() {
// 建立測試案例
int[] test1 = new int[] { 0, 1, 2 };
int[] test2 = new int[] { 10, 4, 16, 54, 17, -7, 21, 15, 25, 31, 61, 1, 6, 12, 21, 46, 16, 56, 54, 12, 23, 20,
38, 63, 2, 27, 35, 11, 13, 47, 13, 11, 61, 39, 0, 14, 42, 8, 16, 54, 50, 12, -10, 43, 11, -1, 24, 38,
-10, 13, 60, 0, 44, 11, 50, 33, 48, 20, 31, -4, 2, 54, -6, 51, 6 };
int[] test3 = new int[] { 0, 1, 2, 3, 5 };
int[] test4 = new int[] { 2 };
// 測試案例期望值
int expResult1 = 3;
int expResult2 = 3;
int expResult3 = 4;
int expResult4 = 1;
Solution041 solution041 = new Solution041();
int result1 = solution041.firstMissingPositive(test1);
int result2 = solution041.firstMissingPositive(test2);
int result3 = solution041.firstMissingPositive(test3);
int result4 = solution041.firstMissingPositive(test4);
Assert.assertEquals(expResult1, result1);
Assert.assertEquals(expResult2, result2);
Assert.assertEquals(expResult3, result3);
Assert.assertEquals(expResult4, result4);
}
其他
程式碼託管碼雲地址:https://gitee.com/lizhaoandroid/LeetCodeAll.git
檢視其他內容可以點選專欄或者我的部落格哈:https://blog.csdn.net/cmqwan
“大佬們的答案” 標籤來自leetcode,侵權請聯絡我進行刪改
如有疑問請聯絡,聯絡方式:QQ3060507060