怎么刷算法,leetcode上有哪些經典題目
合并兩個有序數組
給你兩個按 非遞減順序 排列的整數數組 nums1 和 nums2,另有兩個整數 m 和 n ,分別表示 nums1 和 nums2 中的元素數目。
請你 合并 nums2 到 nums1 中,使合并后的數組同樣按 非遞減順序 排列。
注意:最終,合并后數組不應由函數返回,而是存儲在數組 nums1 中。為了應對這種情況,nums1 的初始長度為 m + n,其中前 m 個元素表示應合并的元素,后 n 個元素為 0 ,應忽略。nums2 的長度為 n 。
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
for (int i = 0; i != n; ++i) {
nums1[m + i] = nums2[i];
}
Arrays.sort(nums1);
}
}
2.刪除有序數組中的重復項
給你一個 升序排列 的數組 nums ,請你 原地 刪除重復出現的元素,使每個元素 只出現一次 ,返回刪除后數組的新長度。元素的 相對順序 應該保持 一致 。然后返回 nums 中唯一元素的個數。
考慮 nums 的唯一元素的數量為 k ,你需要做以下事情確保你的題解可以被通過:
- 更改數組 nums ,使 nums 的前 k 個元素包含唯一元素,并按照它們最初在 nums 中出現的順序排列。nums 的其余元素與 nums 的大小不重要。
- 返回 k 。
public int removeDuplicates(int[] nums) {
if(nums == null || nums.length == 0) return 0;
int p = 0;
int q = 1;
while(q < nums.length){
if(nums[p] != nums[q]){
nums[p + 1] = nums[q];
p++;
}
q++;
}
return p + 1;
}
3.O(1) 時間插入、刪除和獲取隨機元素
實現RandomizedSet 類:
- RandomizedSet() 初始化 RandomizedSet 對象
- bool insert(int val) 當元素 val 不存在時,向集合中插入該項,并返回 true ;否則,返回 false 。
- bool remove(int val) 當元素 val 存在時,從集合中移除該項,并返回 true ;否則,返回 false 。
- int getRandom() 隨機返回現有集合中的一項(測試用例保證調用此方法時集合中至少存在一個元素)。每個元素應該有 相同的概率 被返回。
你必須實現類的所有函數,并滿足每個函數的 平均 時間復雜度為 O(1) 。
class RandomizedSet {
HashMap<Integer, Integer> map;
List<Integer> arr;
int size;
Random random;
public RandomizedSet() {
arr = new ArrayList<>();
map = new HashMap<>();
random = new Random();
size = 0;
}
public boolean insert(int val) {
if (map.containsKey(val)) {
return false;
}
arr.add(val);
map.put(val, size);
size++;
return true;
}
public boolean remove(int val) {
if (!map.containsKey(val)) {
return false;
}
size--;
int key = map.get(val);
int end_val = arr.get(size);
//交換末尾元素和當前元素
swapArr(key, size);
swapMap(key, val, size, end_val);
//刪除末尾的值
arr.remove(size);
map.remove(val);
return true;
}
public void swapArr(int l, int r) {
if (Objects.equals(arr.get(l), arr.get(r))) {
return;
}
int temp = arr.get(l);
arr.set(l, arr.get(r));
arr.set(r, temp);
}
public void swapMap(int l_key, int l_val, int r_key, int r_val) {
if (l_key == r_key) {
return;
}
map.put(l_val, r_key);
map.put(r_val, l_key);
}
public int getRandom() {
int pivot = random.nextInt(size);
return arr.get(pivot);
}
}
作者:15066212pp
鏈接:https://leetcode.cn/problems/insert-delete-getrandom-o1/solutions/2392594/yun-xing-shi-jian-22msha-xi-biao-by-1506-5qcx/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
4.反轉字符串中的單詞
給你一個字符串 s ,請你反轉字符串中 單詞 的順序。
單詞 是由非空格字符組成的字符串。s 中使用至少一個空格將字符串中的 單詞 分隔開。
返回 單詞 順序顛倒且 單詞 之間用單個空格連接的結果字符串。
注意:輸入字符串 s中可能會存在前導空格、尾隨空格或者單詞間的多個空格。返回的結果字符串中,單詞間應當僅用單個空格分隔,且不包含任何額外的空格。
class Solution {
public String reverseWords(String s) {
StringBuilder builder = new StringBuilder(s);
builder.reverse();
int len = 0;
for (int i = 0; i < builder.length(); i++) {
if (builder.charAt(i) == ' ') {
continue;
}
int j = i;
while (j < builder.length() && builder.charAt(j) != ' ') {
j++;
}
if (len > 0) {
builder.setCharAt(len++, ' ');
}
// len + k < j - 1 - k: [0, len + k] 已經是正序 && [j - 1 - k, j] 已經是正序
for (int k = 0; k < j - i && len + k < j - 1 - k; k++) {
swap(builder, len + k, j - 1 - k);
}
len += j - i;
i = j - 1;
}
builder.delete(len, builder.length());
return builder.toString();
}
private void swap(StringBuilder builder, int i, int j) {
char tmp = builder.charAt(i);
builder.setCharAt(i, builder.charAt(j));
builder.setCharAt(j, tmp);
}
}
5.長度最小的子數組
給定一個含有 n 個正整數的數組和一個正整數 target 。
找出該數組中滿足其總和大于等于 target 的長度最小的 連續子數組 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其長度。如果不存在符合條件的子數組,返回 0 。
我們申請一個臨時數組 sums,其中 sums[i] 表示的是原數組 nums 前 i 個元素的和,題中說了 “給定一個含有 n 個 正整數 的數組”,既然是正整數,那么相加的和會越來越大,也就是sums數組中的元素是遞增的。我們只需要找到 sums[k]-sums[j]>=s,那么 k-j 就是滿足的連續子數組,但不一定是最小的,所以我們要繼續找,直到找到最小的為止。怎么找呢,我們可以使用兩個 for 循環來枚舉,但這又和第一種暴力求解一樣了,所以我們可以換種思路,求 sums[k]-sums[j]>=s 我們可以求 sums[j]+s<=sums[k],那這樣就好辦了,因為數組sums中的元素是遞增的,也就是排序的,我們只需要求出 sum[j]+s 的值,然后使用二分法查找即可找到這個 k。
public int minSubArrayLen(int s, int[] nums) {
int length = nums.length;
int min = Integer.MAX_VALUE;
int[] sums = new int[length + 1];
for (int i = 1; i <= length; i++) {
sums[i] = sums[i - 1] + nums[i - 1];
}
for (int i = 0; i <= length; i++) {
int target = s + sums[i];
int index = Arrays.binarySearch(sums, target);
if (index < 0)
index = ~index;
if (index <= length) {
min = Math.min(min, index - i);
}
}
return min == Integer.MAX_VALUE ? 0 : min;
}