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

Cách chuyển thành normal hay nhỉ, mình làm duyệt thấy cùi cùi
C#:
public static bool IsAlienSorted(string[] words, string order)
    {
        var dict = new Dictionary<char, int>();
        for (var index = 0; index < order.Length; index++)
        {
            dict.Add(order[index], index);
        }

        for (var i = 0; i < words.Length - 1; i++)
        {
            if (dict[words[i][0]] < dict[words[i+1][0]]) continue;
            var minLength = Math.Min(words[i].Length, words[i + 1].Length);
            for (var index = 0; index < minLength; index++)
            {
                var dif = dict[words[i][index]] - dict[words[i + 1][index]];
                if (dif > 0) return false;
                if (dif < 0) break;
                if (index == minLength -1 && words[i].Length > words[i + 1].Length) return false;
            }
        }

        return true;
 
Bài hôm nay khó chịu ghê
Mình làm cách dễ nhất là chuyển chuỗi zigzag vào mảng 2 chiều rồi lặp lấy kết quả
Đang tìm hướng giải bằng toán
Java:
class Solution {
    public String convert(String s, int numRows) {
        if(numRows==1) return s;
        int n=s.length();
        int[][] a=new int[n][3];
        int r=0;
        int c=0;
        boolean up=true;
        for(int i=0;i<n;++i){
            a[i][0]=i;
            a[i][1]=r;
            a[i][2]=c;
            if(up){
                if(r==numRows-1){
                    up=!up;
                    r=numRows-2;
                    ++c;
                }
                else{
                    ++r;
                }
            }
            else{
                if(r==0){
                    up=!up;
                    ++r;
                }
                else{
                    --r;
                    ++c;
                }
            }
        }
        Arrays.sort(a, new Comparator<int[]>(){
            public int compare(int[] a, int[] b){
                if(a[1]!=b[1]) return a[1]-b[1];
                return a[2]-b[2];
            }
        });
        StringBuilder res=new StringBuilder();
        for(int i=0;i<a.length;++i){
            res.append(s.charAt(a[i][0]));
        }
        return res.toString();
    }
}
Java:
class Solution {
    public String convert(String s, int numRows) {
        if(numRows==1) return s;
        int n=s.length();
        StringBuilder res=new StringBuilder();
        for(int r=0;r<numRows;++r){
            boolean step1=true;
            int j=r;
            while(j<s.length()){
                res.append(s.charAt(j));
                if(r==0 || r==numRows-1){
                    j+=(2*(numRows-1));
                }
                else{
                    if(step1){
                        j+=(2*(numRows-1-r));
                    }
                    else{
                        j+=(2*r);
                    }
                    step1=!step1;
                }
            }
        }
        return res.toString();
    }
}
 
Last edited:
Bài hôm nay mức độ same same easy mà ko biết sao lại là medium :confused:

JavaScript:
function convert(s, numRows) {
      if (s.length <= numRows || numRows === 1) return s
        const rowString = new Array(numRows).fill('')

        let curRow = 0, result = '', direction = 1
        for (let i = 0; i < s.length; i++) {
            rowString[curRow] += s[i] || ''
            if (curRow === numRows - 1) {
            direction = -1
            } else if (curRow === 0) {
            direction = 1
            }
            curRow += direction
        }

        return rowString.join('')
};
 
Last edited:
Rat la toan
Code:
class Solution {
    public String convert(String s, int numRows) {
        if (numRows == 1) return s;
        char[] c = s.toCharArray();
        int a = 2*numRows -2;
        int x = a - 2;
        int y = 2;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < numRows; i++){
            if (i == 0 || i == numRows - 1) {
                int index = i;
                while(index < c.length) {
                    sb.append(c[index]);
                    index += a;
                }
                continue;
            }
            
            int cnt = 0;
            int index = i;
            while(index < c.length) {
                sb.append(c[index]);
                if (cnt % 2 == 0) {
                    index += x;
                } else {
                    index += y;
                }
                cnt++;
            }
            x -=2;
            y +=2;
        }
        return sb.toString();
    }
}
 
JavaScript:
var convert = function(s, numRows) {
    if (numRows === 1) {
        return s;
    }

    const rows = Array(numRows).fill().map(() => []);
    let i = 0;

    outer: while (true) {
        for (let j = 0; j < (numRows - 1) * 2; j++) {
            const ch = s[i++];
            if (!ch) {
                break outer;
            }
            const rowIndex = (j < numRows) ? j : ((numRows - 1) * 2 - j);
            rows[rowIndex].push(ch);
        }
    }

    return rows.map(it => it.join('')).join('');
};
 
Ý tưởng: Tính từng dòng 1 sau đó cộng vào với nhau. Sử dụng biến đếm row để xác định dòng hiện tại, nếu row max thì giảm 1 dòng, nếu đến 0 thì lại bắt đầu cộng lại -> zigzag

JavaScript:
function convert(s: string, numRows: number) {
    if (s.length === 1 || numRows === 1 || s.length <= numRows) {
        return s;
    }
    const rowStr = new Array(numRows).fill('')

    let row = 0, add = 1
    for (let i = 0; i < s.length; i++) {
        rowStr[row] += s[i] || ''
        if (row === numRows - 1) {
            add = -1
        }
        if (row === 0) {
            add = 1
        }
        row += add
    }

    return rowStr.join('')
};
 
Làm giống bác nào đó ở trên.

JavaScript:
function convert(s: string, numRows: number): string {
  const sLenght = s.length
  if (sLenght <= numRows || numRows === 1 ) return s
  const array = []

  let y = 0
  let direction = 1
  for (let i = 0; i < sLenght; i++) {
    array[y] = (array[y] || '').concat(s[i])
    if (y === 0) {
      direction = 1
    }
    if (y === numRows-1) {
      direction = -1
    }
    y = y + direction
  }

  return array.join('')
}
 
99% Time, 95% Men :D

C++:
class Solution {
public:
    string convert(string s, int numRows) {
        if (numRows == 1)
            return s;
            
        int n = s.size(), sz = 0;
        string ans;
        ans.resize(n);

        for (int r = 0; r < numRows; r++) {
            int pos = r;
            for (int i = 0; i < n / numRows * 2 + 1 && pos < n; ++i) {
                ans[sz] = s[pos];
                if (i % 2 == 0)
                    pos += 2*numRows - 2*r - 2;
                else
                    pos += 2*r;
                sz += (r != 0 && r != numRows - 1) || ((r == 0) && (i % 2 == 0)) || ((r == numRows - 1) && (i % 2 == 1));
            }
        }

        return ans;
    }
};
 
Bài hôm này mình thấy chưa tới Medium, duyệt theo row là xong rồi
C#:
public class Solution {
    public string Convert(string s, int numRows) {
        if (numRows == 1 || s.Length == 1 || numRows >= s.Length) return s;

        var distance = numRows * 2 - 2;
        var result = "";
        for (var rowIndex = 0; rowIndex < numRows; rowIndex++)
        {
            var rowFee = distance - rowIndex * 2 > 0 ? distance - rowIndex * 2 : distance;
            result += s[rowIndex];
            var travel = rowFee;
            var nextStop = rowIndex + travel;
            while (nextStop < s.Length)
            {
                result += s[nextStop];
                travel = distance - travel > 0 ? distance - travel : rowFee;
                nextStop += travel;
            }
        }

        return result;
    }
}
 
Lặp zig zag
Python:
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        s1 = []
        if numRows == 1:
            return s

        for i in range(numRows):
            s1.append([])

        idx = 0
        u = 1

        for c in s:
            s1[idx].append(c)
            idx += 1 * u
            if idx == 0 or idx == numRows - 1:
                u = -u
        
        result = ''
        for e in s1:
            result += ''.join(e)

        return result
 
Bài hôm nay dùng thêm một mảng làm index là ra rồi, có vẻ chưa đến mức Medium !
JavaScript:
var convert = function(s, numRows) {
    res = ""
    arr = []
    idx = 0
    inc = 1
    if (numRows === 1) return s
    for (i=0; i<s.length; i++){
        idx += inc
        if (idx>=numRows || (idx === 1 && i>0)) inc*=-1
        console.log(i," ", idx)
        arr.push(idx)
    }
    console.log(arr)
    for (i=1; i<=numRows;i++)
        for (j=0; j<s.length; j++)
            if (arr[j] === i) res = res.concat(s[j])
    return res
};
 
C++:
class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1) return s;
   
        string res = "";
        int n = s.size();
        for(int i = 0; i < numRows; ++i){
            for(int j = i; j < n; j += 2 * numRows - 2){
                res += s[j];
                if(i != 0 && i != numRows - 1){
                    int k = j + 2 * numRows - 2 - 2 * i;
                    if(k < n) res += s[k];
                }
            }
        }
        return res;
    }
};
 
Hôm nay ngày nghỉ nên chưa ai giải đăng lời giải nhỉ :)
Mình lấy mảng con rồi so sánh nên chạy hơi kém, bên mục Solution của leetcode chắc sẽ có đáp án tốt hơn :)

JavaScript:
var checkInclusion = function(s1, s2) {
    var getDic = function(obj){
        let dic = {}
        for (let i=0; i<obj.length; i++)
            if (obj[i] in dic) dic[obj[i]] +=1
            else dic[obj[i]]=1
        return dic
    }
    var compareObj = function(obj1, obj2){
        let keys1 = Object.keys(obj1)
        let keys2 = Object.keys(obj2)       
        return (keys1.length === keys2.length) && Object.keys(obj1).every(key => obj1[key] === obj2[key])
    }
    
    let s1Dic = getDic(s1)
    for (let i=0; i<= (s2.length-s1.length); i++){
        if (compareObj(s1Dic, getDic(s2.slice(i,i+s1.length))) ) return true
    }
    return false
};
 
Hôm nay ngày nghỉ nên chưa ai giải đăng lời giải nhỉ :)
Mình lấy mảng con rồi so sánh nên chạy hơi kém, bên mục Solution của leetcode chắc sẽ có đáp án tốt hơn :)

JavaScript:
var checkInclusion = function(s1, s2) {
    var getDic = function(obj){
        let dic = {}
        for (let i=0; i<obj.length; i++)
            if (obj[i] in dic) dic[obj[i]] +=1
            else dic[obj[i]]=1
        return dic
    }
    var compareObj = function(obj1, obj2){
        let keys1 = Object.keys(obj1)
        let keys2 = Object.keys(obj2)       
        return (keys1.length === keys2.length) && Object.keys(obj1).every(key => obj1[key] === obj2[key])
    }
    
    let s1Dic = getDic(s1)
    for (let i=0; i<= (s2.length-s1.length); i++){
        if (compareObj(s1Dic, getDic(s2.slice(i,i+s1.length))) ) return true
    }
    return false
};
Chắc ko cần dùng dict đâu, vì có mỗi 26 char và get dc trực tiếp index nên xài array sẽ lợi mem hơn
 
Chắc ko cần dùng dict đâu, vì có mỗi 26 char và get dc trực tiếp index nên xài array sẽ lợi mem hơn
Umh, mình mới xem code của bác nào đấy chạy nhanh nhất, thấy get trực tiếp từ biến đầu vào lợi hơn hẳn :)
 
JavaScript:
/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
var checkInclusion = function(s1, s2) {
    const m = s1.length, n = s2.length;
    if (m > n) {
        return false;
    }

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

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

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

        if (i - j + 1 === m) {
            return true;
        }
    }

    return false;
};
 
100% TC :D
C++:
class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        int letter[26] = {0};
        int count = 0;
        for (auto c: s1) {
            count += (letter[c - 'a']++ == 0);
        }
        
        for (int i = 0; count != 0 && i < s2.size(); ++i) {
            int val = --letter[s2[i] - 'a'];
            if (val == 0) {
                count--;
            }
            
            if (i <= s1.size() - 1) {
                continue;
            }
            
            val = ++letter[s2[i - s1.size()] - 'a'];
            if (val == 1) {
                count++;
            }
        }
        
        return count == 0;
    }
};
 
Lúc đầu viết bằng Map mà chạy runtime gần 2s. Dùng sliding windows thì nhanh hơn hẳn




JavaScript:
function checkInclusion(s1: string, s2: string): boolean {
    if (s1.length > s2.length) {
        return false;
    }
    const s1Arr: number[] = Array(26).fill(0)
    const s2Arr: number[] = Array(26).fill(0)
    for (let i = 0; i < s1.length; i++) {
        s1Arr[s1.charCodeAt(i) - 'a'.charCodeAt(0)]++;
        s2Arr[s2.charCodeAt(i) - 'a'.charCodeAt(0)]++;
    }

    let count = 0;
    for (let i = 0; i < 26; i++) {
        if (s1Arr[i] === s2Arr[i])
            count++;
    }

    for (let i = 0; i < s2.length - s1.length; i++) {
        const right = s2.charCodeAt(i + s1.length) - 'a'.charCodeAt(0), left = s2.charCodeAt(i) - 'a'.charCodeAt(0);
        if (count == 26)
            return true;
        s2Arr[right]++;
        if (s2Arr[right] === s1Arr[right]) {
            count++;
        } else if (s2Arr[right] === s1Arr[right] + 1) {
            count--;
        }
        s2Arr[left]--;
        if (s2Arr[left] === s1Arr[left]) {
            count++;
        } else if (s2Arr[left] === s1Arr[left] - 1) {
            count--;
        }
    }
    return count === 26;
};
 
Sliding window
Code:
class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int[] map1 = new int[26];
        int[] map2 = new int[26];
        for (int i = 0; i < s1.length(); i++) {
            map1[s1.charAt(i) - 'a']++;
        }
        int left = 0; int right = 0;
        while (right < s2.length()) {
            map2[s2.charAt(right) - 'a']++;
            if (isEqual(map1, map2)) return true;
            if (right - left + 1 == s1.length()) {
                map2[s2.charAt(left) - 'a']--;
                left++;
            }
            right++;
        }

        return false;
    }

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

        return true;
    }
}
 
Back
Top