thảo luận Leetcode mỗi ngày

Bài hôm nay với mình khoai quá. Dùng cách cổ lổ sĩ vậy.
Bác nào giải thích cách đếm số lần giúp mình được không ?


JavaScript:
function checkInclusion(s1: string, s2: string): boolean {
  const s1Length = s1.length
  const s2Length = s2.length
  if (s1Length > s2Length) return false;
  const s1Sorted = s1.split('').sort().join('');
  let result = false
  for (let i = 0; (i + s1Length) <= s2Length; i++ ) {
    let s2Sorted = s2.slice(i, i + s1Length).split('').sort().join('')
    if (s1Sorted === s2Sorted) {
      result = true
      break
    }
  }
  return result
}
 
Bài hôm nay với mình khoai quá. Dùng cách cổ lổ sĩ vậy.
Bác nào giải thích cách đếm số lần giúp mình được không ?


JavaScript:
function checkInclusion(s1: string, s2: string): boolean {
  const s1Length = s1.length
  const s2Length = s2.length
  if (s1Length > s2Length) return false;
  const s1Sorted = s1.split('').sort().join('');
  let result = false
  for (let i = 0; (i + s1Length) <= s2Length; i++ ) {
    let s2Sorted = s2.slice(i, i + s1Length).split('').sort().join('')
    if (s1Sorted === s2Sorted) {
      result = true
      break
    }
  }
  return result
}

Do bác sort s1 với substring của s2 rồi so sánh chứ thật ra bác có thể dùng một cái map đếm frequency của character trong s1 so sánh với cái map đếm frequency của character trong substring của s2, quá trình so sánh này là O(26) = O(1) do có 26 chữ cái từ a -> z
 
Do bác sort s1 với substring của s2 rồi so sánh chứ thật ra bác có thể dùng một cái map đếm frequency của character trong s1 so sánh với cái map đếm frequency của character trong substring của s2, quá trình so sánh này là O(26) = O(1) do có 26 chữ cái từ a -> z
Hiểu rồi bác.

Mình làm như này.

JavaScript:
function checkInclusion(s1: string, s2: string): boolean {
  const s1Length = s1.length
  const s2Length = s2.length
  if (s1Length > s2Length) return false;
  if (s1 === s2) return true;
  const aCode = 'a'.charCodeAt(0)
  const s1CharFrequenci = Array(26).fill(0)
  const s2CharFrequenci = Array(26).fill(0)
  let result = false
  for (let i = 0; i < s1Length; i++) {
    s1CharFrequenci[s1.charCodeAt(i) - aCode]++
    s2CharFrequenci[s2.charCodeAt(i) - aCode]++
  }
  for (let i = s1Length; i <= s2Length; i++) {
    if (s1CharFrequenci.every((element, index) => element === s2CharFrequenci[index])) {
      result = true
      break
    }
    s2CharFrequenci[s2.charCodeAt(i) - aCode]++
    s2CharFrequenci[s2.charCodeAt(i - s1Length) - aCode]-- 
  } 
  return result
}
 
Mấy bài tìm optimal solution by merging 2 not-optimal như này làm sao mấy bác nhỉ.
Nhớ có thể dùng DP, nhưng ko biết áp dụng vào đây ra sao :sad:
Screenshot 2023-02-04 at 10.34.44.png
 
Last edited:
Mấy bài tìm optimal solution by merging 2 not-optimal như này làm sao mấy bác nhỉ.
Nhớ có thể dùng DP, nhưng ko biết áp dụng vào đây ra sao :sad:
Cái mảng đc sắp xếp rồi thì bác phải liên tưởng đến giải thuật nào chứ. Em cx vừa làm xong.
Code cho bác tham khảo (làm trong contest nên ko gọn lắm):
C++:
class Solution {
public:
    int maximizeWin(vector<int>& p, int k) {
        int n = p.size();
        vector<int> left(n), right(n);
        int res = 1;
        
        
        
        for (int i = 0; i < n; i++) {
            int start = lower_bound(p.begin(), p.end(), p[i] - k) - p.begin();
            left[i] = i - start + 1;
            if (i > 0)
                left[i] = max(left[i], left[i - 1]);
        }
        
        for (int i = n - 1; i >= 0; i--) {
            int end = upper_bound(p.begin(), p.end(), p[i] + k) - p.begin() - 1;
            right[i] = end - i + 1;
            if (i + 1 < n)
                right[i] = max(right[i], right[i + 1]);
        }
        
        
        // for (int i = 0; i < n; i++) {
        //     cout << left[i] << " " << right[i] << endl;
        // }
        for (int i = 0; i < n - 1; i++) {
            res = max(res, left[i] + right[i + 1]);
        }

        
        return res;
    }
};
 
Cái mảng đc sắp xếp rồi thì bác phải liên tưởng đến giải thuật nào chứ. Em cx vừa làm xong.
Code cho bác tham khảo (làm trong contest nên ko gọn lắm):
C++:
class Solution {
public:
    int maximizeWin(vector<int>& p, int k) {
        int n = p.size();
        vector<int> left(n), right(n);
        int res = 1;
        
        
        
        for (int i = 0; i < n; i++) {
            int start = lower_bound(p.begin(), p.end(), p[i] - k) - p.begin();
            left[i] = i - start + 1;
            if (i > 0)
                left[i] = max(left[i], left[i - 1]);
        }
        
        for (int i = n - 1; i >= 0; i--) {
            int end = upper_bound(p.begin(), p.end(), p[i] + k) - p.begin() - 1;
            right[i] = end - i + 1;
            if (i + 1 < n)
                right[i] = max(right[i], right[i + 1]);
        }
        
        
        // for (int i = 0; i < n; i++) {
        //     cout << left[i] << " " << right[i] << endl;
        // }
        for (int i = 0; i < n - 1; i++) {
            res = max(res, left[i] + right[i + 1]);
        }

        
        return res;
    }
};
Instead of learning solutions of LeetCode questions, understand patterns! For ex. If input array is sorted then
• Binary search
• Two pointers

If asked for all permutations/subsets then
- Backtracking

If given a tree then
• DFS
• BFS

If given a graph then
• DFS
• BFS

If given a linked list then
- Two pointers

If recursion is banned then
- Stack

If must solve in-place then
• Swap corresponding values
• Store one or more different values in the same pointer

If asked for maximum/minimum subarray/subset/options then
- Dynamic programming

If asked for top/least K items then
- Heap

If asked for common strings then
• Map
• Trie

Else
• Map/Set for O(1) time & O(n) space
• Sort input for O(nlogn) time and O(1) space •
Không nhớ của fen nào trong thread này, từ lâu lắm r thì phải kk:byebye:

via theNEXTvoz for iPhone
 
Java:
fun checkInclusion(s1: String, s2: String): Boolean {
    var left = 0
    var right = 0
    val originFreqArr = IntArray(26) { -1 }
    for (c in s1) {
        if (originFreqArr[c - 'a'] < 0) {
            originFreqArr[c - 'a'] = 1
        } else {
            originFreqArr[c - 'a']++
        }
    }
    var freqArr = originFreqArr.clone()
    while (right < s2.length) {
        if (freqArr[s2[right] - 'a'] >= 0) {
            if (freqArr[s2[right] - 'a'] == 0) {
                while (left < right && freqArr[s2[right] - 'a'] == 0) {
                    freqArr[s2[left] - 'a']++
                    left++
                }
            }
            freqArr[s2[right] - 'a']--
            right++
            if (right - left == s1.length) return true
       } else {
            right++
            left = right
            freqArr = originFreqArr.clone()
        }
    }
    return false
}
 
Bài hôm nay giống hôm qua quá, bác nào làm bài hôm qua rồi chắc update code xíu là xong :)
Sao tui làm tới case thứ 64 thì nó báo lỗi Output Limit Exceeded, mà lại không có case nếu không tìm ra thì output như thế nào
P/s: Thì ra do nhà mạng 4 chữ làm lag không submit được

JavaScript:
function isAnAnagram(f1: number[], f2:number[]): boolean {
  let result = true
  const f1Length = f1.length
  for (let i = 0; i < f1Length; i++) {
    if (f1[i] !== f2[i]) {
      result = false
      break
    }
  }

  return result
}

function findAnagrams(s: string, p: string): number[] {
  let result = []
  const sLength = s.length
  const pLength = p.length
  if (sLength < pLength) return result
  const aCode = 'a'.charCodeAt(0)
  const sFrequenci = Array(26).fill(0)
  const pFrequenci = Array(26).fill(0)
  for (let i = 0; i < pLength; i++) {
    pFrequenci[p.charCodeAt(i) - aCode]++
    sFrequenci[s.charCodeAt(i) - aCode]++
  }
  if (sLength === pLength && isAnAnagram(pFrequenci, sFrequenci)) {
    return [0]
  }
  for (let i = pLength; i <= sLength; i++) {
    if (isAnAnagram(pFrequenci, sFrequenci)) {
      result.push(i - pLength)
    }
    sFrequenci[s.charCodeAt(i) - aCode]++
    sFrequenci[s.charCodeAt(i - pLength) - aCode]--
  }
  return result
};
 
Code:
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        if (p.length() > s.length()) return new ArrayList<>();
        int[] map1 = new int[26];
        int[] map2 = new int[26];

        for (int i = 0; i < p.length(); i++) {
            map1[p.charAt(i) - 'a']++;
        }

        List<Integer> ans = new ArrayList<>();
        int left = 0, right = 0;
        while (right < s.length()) {
            if (right - left + 1 > p.length()) {
                map2[s.charAt(left) - 'a']--;
                left++;
            }
            map2[s.charAt(right) - 'a']++;
            if (isEqual(map1, map2)) ans.add(left);
            right++;
        }
        return ans;
    }

    public boolean isEqual(int[] map1, int[] map2) {
        for (int i = 0; i <= 25; i++) {
            if (map1[i] != map2[i]) return false;
        }

        return true;
    }
}
 
JavaScript:
/**
 * @param {string} s
 * @param {string} p
 * @return {number[]}
 */
var findAnagrams = function(s, p) {
    const m = p.length, n = s.length;

    if (m > n) {
        return [];
    }

    const g = Array(26).fill(0);
    for (const ch of p) {
        g[ch.charCodeAt(0) - 97]++;
    }

    let j = 0, ans = [];
    for (let i = 0; i < n; i++) {
        const charIdx = s.charCodeAt(i) - 97;
        g[charIdx]--;

        while (g[charIdx] < 0) {
            g[s.charCodeAt(j++) - 97]++;
        }

        if (i - j + 1 === m) {
            ans.push(j);
        }
    }

    return ans;
};
 
Python:
class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        if (len(p) > len(s)):
            return []
        result = []
        freq = create_freq_array(p)
        current_freq = {}
        for start in range(0, len(s) - len(p) + 1):
            if start == 0:
                for index in range(start, len(p)):
                    push_dict(current_freq, s[index])
            else:
                push_dict(current_freq, s[start + len(p) - 1])

            flag = True
            for key in current_freq:
                if freq[ord(key) - 97] != current_freq[key]:
                    flag = False
                    break

            if flag:
                result.append(start)

            current_freq[s[start]] -= 1

        return result

def create_freq_array(s: str):
    freq = [0 for i in range(26)]
    for c in s:
        freq[ord(c) - 97] += 1

    return freq

def push_dict(dict: {}, c: str):
    if c in dict:
        dict[c] += 1
    else:
        dict[c] = 1
 
Y hệt bài hôm qua :D
Java:
fun findAnagrams(s: String, p: String): List<Int> {
        val result = mutableListOf<Int>()
        var left = 0
        var right = 0
        val originFreqArr = IntArray(26) { -1 }
        for (c in p) {
            if (originFreqArr[c - 'a'] < 0) {
                originFreqArr[c - 'a'] = 1
            } else {
                originFreqArr[c - 'a']++
            }
        }
        var freqArr = originFreqArr.clone()
        while (right < s.length) {
            if (freqArr[s[right] - 'a'] >= 0) {
                if (freqArr[s[right] - 'a'] == 0) {
                    while (left < right && freqArr[s[right] - 'a'] == 0) {
                        freqArr[s[left] - 'a']++
                        left++
                    }
                }
                freqArr[s[right] - 'a']--
                right++
                if (right - left == p.length) {
                    result.add(left)
                    freqArr[s[left] - 'a']++
                    left++
                }
            } else {
                right++
                left = right
                freqArr = originFreqArr.clone()
            }
        }
        return result
    }
 
bài hôm nay có giải đc array in-place ko ae. Chứ tạo mảng mới thì ez quá:after_boom:

JavaScript:
function shuffle(nums: number[], n: number): number[] {
    if (nums.length === 2) {
        return nums;
    }
    let arr: number[] = [];
    for (let i = 0; i < n; i++) {
        arr.push(nums[i]);
        arr.push(nums[i+n]);
    }
    return arr;
};
 
Được hôm code 5 phút.
JavaScript:
function shuffle(nums: number[], n: number): number[] {
  const result = []
  for (let i = 0; i < n; i++) {
    result.push(nums[i], nums[n+i])
  }
  return result
};
 
Back
Top