LeetCode 30天刷题计划

LeetCode 30天刷题计划

为了在一个月内高效地刷题,下面的计划每天安排了2道题目,总共60道题目。题目难度从简单到困难逐步增加,题目涵盖了常见的算法和数据结构主题。

第1周

第1天

  1. Two Sum
function twoSum(nums: number[], target: number): number[] {
    let res : [number, number] = [0, 0];
    let map : Map<number, number> = new Map();

    for (let i = 0;i< nums.length ;i ++) {
        if (map.has(nums[i]) && map.get(nums[i]) !== i) {
            res = [i, map.get(nums[i])];
            break;
        } else {
            map.set(target - nums[i], i);
        }
    }

   return res;

};
  1. Reverse Integer
function reverse(x: number): number {
    const num: number = Math.abs(x);

    const str: string = String(x).split('').reverse().join('');

    const res = x < 0 ? -parseInt(str) : parseInt(str);
    if (res < -Math.pow(2, 31) || res > Math.pow(2, 31)) return 0
    return res
};

第2天

  1. Palindrome Number

我自己的解法:双指针

function isPalindrome(x: number): boolean {
    if (x < 0) return false;
    if (x < 10) return true;
    
    const str = x + '';

    let p1 = 0;
    let p2 = str.length - 1;

    while(p2 - p1 >= 0) {
        if (str.charAt(p1) !== str.charAt(p2)) return false;
        
        p1 += 1;
        p2 -= 1;
    }

    return true;

};

网上有人更简单

var isPalindrome = function(x) {
    let y=Number(x.toString().split('').reverse().join(''))
    return y===x
};
  1. Roman to Integer
function intToRoman(num: number): string {
    let y: number = num;
    let r: string = '';
    if (y >= 1000) {
        const n = Math.floor(y / 1000);
        y = y % 1000;

        for (let i = 0; i < n; i++) {
            r += 'M';
        }
    }
    if (y >= 900) {
        y -= 900;
        r += 'CM';
    }
    if (y >= 500) {
        const n = Math.floor((y - 500) / 100);
        y = y % 100;
        r += 'D';
        for (let i = 0; i < n; i++) {
            r += 'C';
        }
    }

    if (y >= 400) {
        y -= 400;
        r += 'CD';
    }

    if (y >= 100) {
        const n = Math.floor(y / 100);
        y = y % 100;

        for (let i = 0; i < n; i++) {
            r += 'C';
        }
    }

    if (y >= 90) {
        y -= 90;

        r += 'XC';
    }

    if (y >= 50) {
        const n = Math.floor((y - 50) / 10);
        y = y % 10;
        r += 'L';
        for (let i = 0; i < n; i++) {
            r += 'X';
        }
    }
    if (y >= 40) {
        y -= 40;
        r += 'XL';
    }

    if (y >= 10) {
        const n = Math.floor(y / 10);
        y = y % 10;

        for (let i = 0; i < n; i++) {
            r += 'X';
        }
    }

    if (y >= 9) {
        y = 0;
        r += 'IX';
    } else if (y >= 5) {
        const n = y - 5;
        y = 0;
        r += 'V';
        for (let i = 0; i < n; i++) {
            r += 'I';
        }
    } else if (y === 4) {
        y = 0;
        r += 'IV';
    } else {
        for (let i = 0; i < y; i++) {
            r += 'I';
        }
        y = 0;
    }

    return r;
};

第3天

  1. Longest Common Prefix

function longestCommonPrefix(strs: string[]): string {
    let res = strs[0];
    
    while(res.length) {
        let allHas: boolean = true;
        for (let s of strs) {
            if (s.indexOf(res) !== 0) {
                allHas = false;
                break;
            }
        }

        if (allHas) return res;

        if (!allHas) {
           res = res.substring(0, res.length - 1);
        }

    }


    return '';

};
  1. Valid Parentheses
function isValid(s: string): boolean {
    const map = new Map();
    map.set('{', '}');
    map.set('(', ')');
    map.set('[', ']');

    const stack: string[] = [];
    for (let c of s) {
        if (map.has(c)) {
            stack.push(c)
        } else {
            const i = stack.pop();
            if (map.get(i) !== c) {
                return false;
            }
        }
    }
    return stack.length === 0;
};

第4天

  1. Merge Two Sorted Lists
    非递归
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

function mergeTwoLists(list1: ListNode | null, list2: ListNode | null): ListNode | null {
    const res = new ListNode(0, null);
    let p = res;

    while (list1 && list2) {
        if (list1.val > list2.val) {
            p.next = list2;
            list2 = list2.next;
        } else {
            p.next = list1;
            list1 = list1.next;
        }
        p = p.next;
    }

    if (list1) p.next = list1;
    if (list2) p.next = list2;


    return res.next;
};
  1. Remove Duplicates from Sorted Array
function removeDuplicates(nums: number[]): number {
    if (nums.length === 0) return 0

    let p = 0, q = 1;

    while (q < nums.length) {
        if (nums[p] === nums[q]) {
            q++;
        } else {
            p++;
            nums[p] = nums[q]
        }
    }


    return p + 1;

};

第5天

  1. Remove Element
function removeElement(nums: number[], val: number): number {
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] === val) nums[i] = null;
    }

    for (let i = 0; i < nums.length; i++) {
        if (nums[i] === null) {

            for (let j = i + 1; j < nums.length; j++) {
                if (nums[j] !== null) {
                    nums[i] = nums[j];
                    nums[j] = null;
                    break;
                }
            }
        }
    }

    while (nums.length > 0 && nums[nums.length - 1] === null) {
        nums.pop();
    }

    return nums.length;
};
  1. Implement strStr()
function strStr(haystack: string, needle: string): number {
    if (haystack === needle) return 0;
    for (let i = 0; i < haystack.length; i++) {
        for (let j = 0; j <= needle.length ; j++) {
            if ( i + j > haystack.length) return -1
            if (j === needle.length) return i;


            if (haystack.charAt(i + j) !== needle.charAt(j)) {
                break
            }

        }
    }

    return -1;
};

第6天

  1. Search Insert Position

思路:二分查找
注意点:边界问题
时间复杂度:log(n)
空间复杂度:O(1)

function searchInsert(nums: number[], target: number): number {
    let start = 0; let end = nums.length - 1;

    if (target <= nums[0]) return 0;

    while (start <= end) {
        const mid = Math.ceil((start + end) / 2);
        if (nums[mid] < target) start = mid + 1;
        else end = mid - 1;
    }

    return start;
};
  1. Count and Say
function countAndSay(n: number): string {
    let str = '1';
    for (let i = 2; i <= n; i++) {
        const sb = [];
        let start = 0;
        let pos = 0;

        while (pos < str.length) {
            while(pos < str.length && str[pos] === str[start]) {
                pos ++;
            }
            sb.push('' + (pos - start) + str[start]);
            start = pos
        }

        str = sb.join('');
    }

    return str;
};

第7天

  1. Maximum Subarray
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function (nums) {
    let pre = nums[0];
    let max = nums[0];

    for (let i of nums.slice(1, nums.length)) {
        pre = Math.max(i, pre + i);
        max = Math.max(max, pre);
    }

    return max;
};

时间复杂度0(n)
思路:动态规划

  1. Length of Last Word
/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLastWord = function(s) {
    const strs = s.trim().split(' ')
    return strs[strs.length - 1].length;
};

第2周

第8天

  1. Plus One
/**
 * @param {number[]} digits
 * @return {number[]}
 */
var plusOne = function(digits) {
    for (let i = digits.length - 1; i >=0 ; i--) {
        const value = digits[i];
        if ((value + 1) % 10 !== 0 ) {
            digits[i] = value + 1;

            return digits;
        } 
        digits[i] = 0
    }

    digits.unshift(1);
    return digits;
};


时间复杂度0(n),n为数据大小

  1. Add Binary
/**
 * @param {string} a
 * @param {string} b
 * @return {string}
 */
var addBinary = function (a, b) {
    let res = "", aArr = a.split(''), bArr = b.split('');
    let flag = 0;
    while (aArr.length || bArr.length) {
        let va, vb;
        va = aArr.length ? aArr.pop() : 0;
        vb = bArr.length ? bArr.pop() : 0;

        res = (parseInt(va, 10) + parseInt(vb, 10) + flag) % 2 + '' + res;
        flag = Math.floor(parseInt(va, 10) + parseInt(vb) + flag  % 2)
    }

    if (flag) {
        res = '1' + res;
    }

    return res;
};

时间复杂度0(n),n为最大数组的长度

第9天

  1. Climbing Stairs
/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function(n) {
    let p = 0, q = 0, r = 1;
    for(let i = 1; i <= n; i++) {
        p = q;
        q = r;
        r = p + q;
    }

    return r;
};

思路:动态规划 + 滑动窗口
时间复杂度: O(n)

  1. Remove Duplicates from Sorted List
    var deleteDuplicates = function (head) {

    if (!head || !head.next) return head

    let p = head;
    while (p.next) {
    if (p.val === p.next.val) {
    p.next = p.next.next;
    } else {
    p = p.next;
    }

    }
    return head;

};

时间复杂度 O(n)n为链表长度

第10天

  1. Merge Sorted Array
var merge = function (nums1, m, nums2, n) {
    let p = 0, q = 0, size = m;
    while (p < size || q < n) {
        const a = nums1[p], b = nums2[q];
        if (a > b) {
            // 插入a
            size++;
            insert(nums1, size, p, b,);
            q++;
        } else if (p >= size) {
            nums1[p] = b;
            q++;
        }
        p++;
    }

};
时间复杂度 O(m + n)

function insert(arr, len, index, value) {
    let cur = len - 1;
    while (cur >= index) {
        if (cur > index) arr[cur] = arr[cur - 1];
        else {
            arr[cur + 1] = arr[cur];
            arr[cur] = value;
        }

        cur--;
    }
}
  1. Binary Tree Inorder Traversal
var inorderTraversal = function(root) {
    const res = [];

    function tra(node) {
        if (!node) return;

        tra(node.left);
        res.push(node.val);
        tra(node.right)
    }

    tra(root);

    return res;
};

时间复杂度O(n)n为节点个数

第11天

  1. Symmetric Tree
var isSymmetric = function (root) {

    function same(tree1, tree2) {
        if (!tree1 && !tree2) return true;
        if (tree1 && tree2) {
            return tree1.val === tree2.val && same(tree1.left, tree2.right) && same(tree1.right, tree2.left)
        }

        return false;
    }


    return same(root.left, root.right)
};

时间复杂度O(n) n为树节点个数

  1. Maximum Depth of Binary Tree

/**
 * 深度优先
 * @param {TreeNode} root
 * @return {number}
 */

var maxDepth = function (root) {
    if (!root) {
        return 0
    }

    return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
};

广度优先

var maxDepth = function (root) {
    if (!root) return 0;

    const queue = [root];
    let res = 0;

    while (queue.length > 0) {
        let size = queue.length;

        while (size > 0) {
            const node = queue.shift();
            if (node.left) {
                queue.push(node.left);
            }

            if (node.right) {
                queue.push(node.right)
            }

            size--;
        }
        res++;
    }

    return res;

};

第12天

  1. Best Time to Buy and Sell Stock
  2. Single Number

第13天

  1. Linked List Cycle
  2. Min Stack

第14天

  1. Number of 1 Bits
  2. Happy Number

第3周

第15天

  1. Reverse Linked List
  2. Intersection of Two Linked Lists

第16天

  1. Find the Duplicate Number
  2. Missing Number

第17天

  1. Contains Duplicate
  2. Product of Array Except Self

第18天

  1. Maximum Product Subarray
  2. Find Minimum in Rotated Sorted Array

第19天

  1. Search in Rotated Sorted Array
  2. Find Peak Element

第20天

  1. First Missing Positive
  2. Longest Consecutive Sequence

第21天

  1. Valid Sudoku
  2. Sudoku Solver

第4周

第22天

  1. Word Search
  2. Word Search II

第23天

  1. Set Matrix Zeroes
  2. Spiral Matrix

第24天

  1. Rotate Image
  2. Kth Largest Element in an Array

第25天

  1. Top K Frequent Elements
  2. Sort Colors

第26天

  1. Minimum Window Substring
  2. Longest Substring Without Repeating Characters

第27天

  1. Longest Palindromic Substring
  2. Longest Repeating Character Replacement

第28天

  1. Permutation in String
  2. Find All Anagrams in a String

第29天

  1. Longest Increasing Subsequence
  2. Word Break

第30天

  1. House Robber
  2. Coin Change

结论

按照上述计划每天刷2道题目,可以在一个月内完成60道算法题。题目涵盖了常见的算法和数据结构主题,逐步提高难度。希望这个计划能帮助你高效地在LeetCode上刷题,提升算法和编程能力。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容