26-刪除重複元素
給你一個有序陣列 nums ,請你 原地 刪除重複出現的元素,使每個元素 只出現一次 ,返回刪除後陣列的新長度。
不要使用額外的陣列空間,你必須在 原地 修改輸入陣列 並在使用 O(1) 額外空間的條件下完成。
連結:leetcode-cn.com/problems/remove-du...
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) {
return 0;
}
if (nums.length == 1) {
return 1;
}
int slow = 1;
int fast = 1;
// 1 2 2 3
while (fast < nums.length) {
if (nums[fast] != nums[fast - 1]) {
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
}
27-移除元素
給你一個陣列 nums 和一個值 val,你需要 原地 移除所有數值等於 val 的元素,並返回移除後陣列的新長度。
不要使用額外的陣列空間,你必須僅使用 O(1) 額外空間並 原地 修改輸入陣列。
元素的順序可以改變。你不需要考慮陣列中超出新長度後面的元素。
連結:leetcode-cn.com/problems/remove-el...
方法一:
public int removeElement(int[] nums, int val) {
// left代表下一個不等於val的下標
int left = 0;
// 遍歷陣列,只要不等於val的就賦值給num[left],同事left++
for (int j = 0; j < nums.length; j++) {
if (nums[j] != val) {
nums[left] = nums[j];
left++;
}
}
return left;
}
方法二:
/**
* 元素的順序可以改變,所以可以使用兩個下標left、right
* left從左向右尋找等於val的元素
* right從右向左尋找不等於val的值
* 最後令nums[right] = num[right]
*/
public int removeElement(int[] nums, int val) {
int left = 0, right = nums.length - 1;
int count = 0;
while (left <= right) {
while (left <= right && nums[left] != val && left < nums.length) {
left++;
count++;
}
while (left <= right && nums[right] == val && right >= 0) {
right--;
}
if (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
count++;
left++;
right--;
}
}
return count;
}
方法三:
public int removeElement(int[] nums, int val) {
int left = 0, right = nums.length;
while (left < right) {
if (nums[left] == val) {
nums[left] = nums[right - 1];
right--;
} else {
left++;
}
}
return left;
}
189-旋轉陣列
給定一個陣列,將陣列中的元素向右移動 k 個位置,其中 k 是非負數。
進階:
儘可能想出更多的解決方案,至少有三種不同的方法可以解決這個問題。
你可以使用空間複雜度為 O(1) 的 原地 演算法解決這個問題嗎?
示例 1:
輸入: nums = [1,2,3,4,5,6,7], k = 3
輸出: [5,6,7,1,2,3,4]
解釋:
向右旋轉 1 步: [7,1,2,3,4,5,6]
向右旋轉 2 步: [6,7,1,2,3,4,5]
向右旋轉 3 步: [5,6,7,1,2,3,4]
連結:leetcode-cn.com/problems/rotate-ar...
暴力法會超時
// 會超時
public void rotate(int[] nums, int k) {
k = k % nums.length;
for (int i = 0; i < k; i++) {
int last = nums[nums.length - 1];
for (int j = nums.length - 1; j > 0; j--) {
nums[j] = nums[j - 1];
}
nums[0] = last;
}
}
透過找規律可以發現,翻轉後的陣列,將前k個翻轉並且將剩下的(l-k)個也翻轉,最後得到的資料為原始陣列翻轉後的結果。
因此我們可以先把整個陣列翻轉,然後將k個元素翻轉,最後將後(l-k)個元素也翻轉
public void rotate(int[] nums, int k) {
k = k % nums.length;
fun(nums, 0, nums.length - 1);
fun(nums, 0, k - 1);
fun(nums, k, nums.length - 1);
}
public void fun(int[] nums, int left, int right) {
while (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
300-最長遞增子序列
給你一個整數陣列 nums ,找到其中最長嚴格遞增子序列的長度。
子序列是由陣列派生而來的序列,刪除(或不刪除)陣列中的元素而不改變其餘元素的順序。例如,[3,6,2,7] 是陣列 [0,3,1,6,2,2,7] 的子序列。
連結:leetcode-cn.com/problems/longest-i...
class Solution {
/**
* dp[i] = max(dp[j] + 1, dp[i]), 0 <= j < i
* [0,3,1,6,2,2,7]
*/
public int lengthOfLIS(int[] nums) {
if (nums.length == 1) {
return 1;
}
int[] dp = new int[nums.length];
dp[0] = 1;
int max = 1;
for (int i = 1; i < nums.length; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
// 找到比當前i的值小了
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[j] + 1, dp[i]);
max = Math.max(max, dp[i]);
}
}
}
return max;
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結