Deckkker 普通 2024年4月27日 下午4:24

    本打卡对应问题:【基本数据结构】剑指 Offer 09. 用两个栈实现队列
    具体打卡内容:

    class CQueue:

    def __init__(self):
        self.Stack_In = []
        self.Stack_Out = []
    
    def appendTail(self, value: int) -> None:
        self.Stack_In.append(value)
    
    def deleteHead(self) -> int:
        if self.Is_empty():
            return -1
    
        if self.Stack_Out:
            return self.Stack_Out.pop()
        else:
            while self.Stack_In:
                self.Stack_Out.append(self.Stack_In.pop())
            return self.Stack_Out.pop()
    
    def Is_empty(self):
        return not (self.Stack_In or self.Stack_Out)
    

    时间复杂度: O(1),push 为 O(1),pop 为均摊 O(1)。对于每个元素,至多入栈和出栈各两次(Stack_In和Stack_Out至多各进出栈一次),故均摊复杂度为 O(1)。

    空间复杂度:O(n)。其中 n 是操作总数。对于有 n 次 push 操作的情况,队列中会有 n 个元素,故空间复杂度为 O(n)。

    Deckkker 普通 2024年4月27日 下午4:22

    本打卡对应问题:【基本数据结构】LeetCode 225. 用队列实现栈
    具体打卡内容:

    class MyStack:

    def __init__(self):
        self.Que_1 = []
        self.Que_2 = []
    
    def push(self, x: int) -> None:
        # Push element x onto stack. 
        self.Que_1.append(x)
    
    def pop(self) -> int:
        # Removes the element on top of the stack and returns that element.
        while len(self.Que_1)>1:
            self.Que_2.append(self.Que_1.pop(0))
        res = self.Que_1.pop(0)
        self.Que_1, self.Que_2 = self.Que_2, self.Que_1
        self.Que_2.clear()
        return res
    
    def top(self) -> int:
        # Get the top element.
        while len(self.Que_1)>1:
            self.Que_2.append(self.Que_1.pop(0))
        res = self.Que_1[0]
        self.Que_2.append(self.Que_1.pop(0))
        self.Que_1, self.Que_2 = self.Que_2, self.Que_1
        self.Que_2.clear()
        return res
    
    def empty(self) -> bool:
        return not self.Que_1
    

    入栈操作(push):O(1)
    出栈操作(pop):平均情况下接近O(1),最坏情况下O(n)
    获取栈顶元素(top):平均情况下接近O(1),最坏情况下O(n)
    判空操作(empty):O(1)

    Deckkker 普通 2024年4月27日 上午10:51

    本打卡对应问题:剑指 Offer 09. 用两个栈实现队列
    具体打卡内容:

    class CQueue:

    def __init__(self):
        self.Stack_In = []
        self.Stack_Out = []
    
    def appendTail(self, value: int) -> None:
        self.Stack_In.append(value)
    
    def deleteHead(self) -> int:
        if self.Is_empty():
            return -1
    
        if self.Stack_Out:
            return self.Stack_Out.pop()
        else:
            while self.Stack_In:
                self.Stack_Out.append(self.Stack_In.pop())
            return self.Stack_Out.pop()
    
    def Is_empty(self):
        return not (self.Stack_In or self.Stack_Out)
    

    时间复杂度: O(1),push 为 O(1),pop 为均摊 O(1)。对于每个元素,至多入栈和出栈各两次(Stack_In和Stack_Out至多各进出栈一次),故均摊复杂度为 O(1)。

    空间复杂度:O(n)。其中 n 是操作总数。对于有 n 次 push 操作的情况,队列中会有 n 个元素,故空间复杂度为 O(n)。

    Deckkker 普通 2024年4月27日 上午10:22

    本打卡对应问题:【链表专题】百度真题:环形链表分成三等份
    具体打卡内容:

    思路分析

    1. 遍历链表统计长度:首先遍历链表,统计链表的长度。这是为了确定每个部分的长度以及可能存在的剩余节点数。
    2. 计算分割数量和长度:根据给定的分割数量k和链表长度,计算出每个部分的平均长度(即链表长度除以分割数量),以及前面多余的部分的长度(即链表长度对分割数量取余)。
    3. 分割链表:再次遍历链表,根据计算出的长度将链表分割成k个部分,并将每个部分的尾节点的next指针置为空。
    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def splitListToParts(self, head: Optional[ListNode], k: int) -> List[Optional[ListNode]]:
            if not head:
                return [None for _ in range(k)]
    
            length = 0
            node = head
            while node:
                length += 1
                node = node.next
    
            # 计算每段的长度以及多出的部分
            avg_len, extra_len = length//k, length%k 
    
            # 再次遍历链表,根据 avg_len 和 extra_len 将链表分割成 k 个部分
            # 并将每个部分的尾节点的 next 指针置为空。
            res = []
            cur = head
            pre = None
    
            for _ in range(k):
                res.append(cur)
                for _ in range(avg_len+(1 if extra_len > 0 else 0)):
                    pre = cur
                    cur = cur.next
                if pre:
                    pre.next = None
                extra_len -= 1
            return res
    

    复杂度分析

    • 时间复杂度:O(n),其中n是链表的长度,需要遍历链表两次。
    • 空间复杂度:O(1)

    参考力扣725.分隔链表,k恒定为3即可。

    Laboratory 普通 2024年4月18日 上午11:22

    本打卡对应问题:什么是AVL树?
    具体打卡内容:

    阅读打卡

    Laboratory 普通 2024年4月15日 下午11:43

    本打卡对应问题:【基本数据结构】变形题:最小栈的最优解
    具体打卡内容:

    利用差值存入栈中可以保证O(1)的空间复杂度

    Laboratory 普通 2024年4月15日 下午11:29

    本打卡对应问题:【基本数据结构】剑指 Offer 31. 栈的压入、弹出序列
    具体打卡内容:
    class Solution {
        public boolean validateBookSequences(int[] putIn, int[] takeOut) {
            if(putIn.length == 0) {
                return true;
            }
            Deque<Integer> stack = new LinkedList<>();
            int i=0;
            for(int num : putIn) {
                stack.offerLast(num);
                while(!stack.isEmpty() && stack.peekLast() == takeOut[i]) {
                    stack.pollLast();
                    i++;
                }
            }
            return stack.isEmpty();
        }
    }
    

    时间复杂度O(n),空间复杂度O(n)

    Laboratory 普通 2024年4月15日 下午11:04

    本打卡对应问题:【基本数据结构】剑指 Offer 30. 包含min函数的栈
    具体打卡内容:
    class MinStack {
        Deque<Integer> stack;
        Deque<Integer> minStack;
    
        /** initialize your data structure here. */
        public MinStack() {
            stack = new LinkedList<>();
            minStack = new LinkedList<>();
        }
    
        public void push(int x) {
            stack.offerLast(x);
            if(minStack.isEmpty() || x <= minStack.peekLast()) {
                minStack.offerLast(x);
            }
        }
    
        public void pop() {
            int i = stack.pollLast();
            if(i == minStack.peekLast()) {
                minStack.pollLast();
            }
        }
    
        public int top() {
            return stack.peekLast();
        }
    
        public int getMin() {
            return minStack.peekLast();
        }
    }
    
    /**
     * Your MinStack object will be instantiated and called as such:
     * MinStack obj = new MinStack();
     * obj.push(x);
     * obj.pop();
     * int param_3 = obj.top();
     * int param_4 = obj.getMin();
     */
    

    时间复杂度O(1),空间复杂度O(n)

    =.= 普通 2024年4月15日 下午9:50

    本打卡对应问题:【动态规划专题】剑指 Offer 49. 丑数
    具体打卡内容:

    class Solution {
    public int nthUglyNumber(int n) {
    int a = 1, b = 1, c = 1;
    int[] dp = new int[n+1];
    dp[1] = 1;
    for(int i=2; i<=n; i++){
    dp[i] = Math.min(dp[a]2, Math.min(dp[b]3, dp[c]5));
    if(dp[i] dp[a]
    2) a++;
    if(dp[i] dp[b]3) b++;
    if(dp[i] dp[c]
    5) c++;
    }

        return dp[n];
    }
    

    }

    时间:O(n);
    空间:O(n)

    王位詮釋 普通 2024年4月15日 下午3:10

    本打卡对应问题:【杂题】剑指 Offer 29. 顺时针打印矩阵
    具体打卡内容:
    class Solution {
        public int[] spiralArray(int[][] array) {
            if(array==null||array.length==0){
                return new int[0];
            }
            int m = array.length;
            int n = array[0].length;
            int[] res = new int[m*n];
            int up = 0;//上边界
            int down = m-1;//下边界
            int left = 0;//左边界
            int right = n-1;//右边界
            int index = 0;
            while(up<=down||left<=right){
                //往右走
                for(int i=left;i<=right;i++){
                    res[index++] = array[up][i];
                }
                up++;
                if(up>down){
                    break;
                }
                //往下走
                for(int i=up;i<=down;i++){
                    res[index++] = array[i][right];
                }
                right--;
                if(right<left){
                    break;
                }
                //往左走
                for(int i = right;i>=left;i--){
                    res[index++] = array[down][i];
                }
                down--;
                if(down<up){
                    break;
                }
                //往上走
                for(int i = down;i>=up;i--){
                    res[index++] = array[i][left];
                }
                left++;
                if(left>right){
                    break;
                }
            }
            return res;
        }
    }
    思路:定义左边界、有边界、上边界和下边界,然后可以向右走、向下走、
    向左走和向上走,同时创建一个res数组用来保存访问到的数组元素
    时间复杂度:O(mn)
    空间复杂度:O(1)
    
    =.= 普通 2024年4月15日 下午2:57

    本打卡对应问题:【动态规划专题】剑指 Offer 48. 最长不含重复字符的子字符串
    具体打卡内容:

    class Solution {
    public int dismantlingAction(String arr) {
    int n = arr.length();
    int ans = 0;

        int left = 0;
        int right = 0;
        HashMap<Character, Integer> window = new HashMap<>();
    
        while(right < n){
            char c = arr.charAt(right);
            right++;
            window.put(c, window.getOrDefault(c, 0) + 1);
            if(window.get(c) == 1){
                ans = Math.max(ans, window.size());
            }
    
            while(window.get(c) > 1){
                char d = arr.charAt(left);
                if(window.get(d)>1){
                    window.put(d, window.get(d)-1);
                }
                else{
                    window.remove(d);
                }
                left++;
            }
        }
    
        return ans;
    }
    

    }

    时间:O(n)
    空间:O(n)

    =.= 普通 2024年4月15日 下午2:36

    本打卡对应问题:【动态规划专题】剑指 Offer 47. 礼物的最大价值
    具体打卡内容:

    class Solution {
    public int jewelleryValue(int[][] frame) {
    int m = frame.length;
    int n = frame[0].length;

        int[][] dp = new int[m][n];
        dp[0][0] = frame[0][0];
        for(int j=1; j<n; j++){
            dp[0][j] = dp[0][j-1] + frame[0][j];
        }
        for(int i=1; i<m; i++){
            dp[i][0] = dp[i-1][0] + frame[i][0];
        }
    
        for(int i=1; i<m; i++){
            for(int j=1; j<n; j++){
                dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]) + frame[i][j];
            }
        }
    
        return dp[m-1][n-1];
    }
    

    }

    时间:O(mn)
    空间:O(mn)

    =.= 普通 2024年4月15日 下午2:28

    本打卡对应问题:【动态规划专题】剑指 Offer 63. 股票的最大利润
    具体打卡内容:

    class Solution {
    public int bestTiming(int[] prices) {
    int n = prices.length;
    if(n <= 1) return 0;

        int min = prices[0];
        int ans = 0;
    
        for(int i=1; i<n; i++){
            ans = Math.max(ans, prices[i] - min);
            min = Math.min(min, prices[i]);
        }
    
        return ans;
    }
    

    }

    时间:O(n)
    空间:O(1)

    王位詮釋 普通 2024年4月15日 下午2:25

    本打卡对应问题:【杂题】剑指 Offer 04. 二维数组中的查找
    具体打卡内容:
    暴力法:
    class Solution {
        public boolean findTargetIn2DPlants(int[][] plants, int target) {
            //暴力法
            if(plants==null||plants.length==0){
                return false;
            }
            int m = plants.length;
            int n = plants[0].length;
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(plants[i][j]==target){
                        return true;
                    }
                }
            }
            return false;
        }
    }
    时间复杂度:O(n2)
    空间复杂度:O(1)
    
    最优解:
    class Solution {
        public boolean findTargetIn2DPlants(int[][] plants, int target) {
            if(plants==null||plants.length<=0){
                return false;
            }
            int i = plants.length-1;
            int j = 0;
            while(i>=0&&j<plants[0].length){
                if(plants[i][j]==target){
                    return true;
                }
                if(plants[i][j]<target){
                    j++;
                }else{
                    i--;
                }
            }
            return false;
        }
    }
    时间复杂度:O(m+n)
    空间复杂度:O(1)
    
    王位詮釋 普通 2024年4月15日 下午2:09

    本打卡对应问题:【杂题】剑指 Offer 03. 数组中重复的数字
    具体打卡内容:
    哈希表法:
    class Solution {
        public int findRepeatDocument(int[] documents) {
            Set<Integer> set = new HashSet<>();
            for(int i=0;i<documents.length;i++){
                if(set.contains(documents[i])){
                    return documents[i];
                }else{
                    set.add(documents[i]);
                }
            }
            return -1;
        }
    }
    时间复杂度:O(n)
    空间复杂度:O(n)
    
    排序法:
    class Solution {
        public int findRepeatDocument(int[] documents) {
            Arrays.sort(documents);
            for(int i=1;i<documents.length;i++){
                if(documents[i]==documents[i-1]){
                    return documents[i];
                }
            }
            return -1;
        }
    }
    时间复杂度:O(nlogn)
    空间复杂度:O(1)
    
    下标法:
    class Solution {
        public int findRepeatDocument(int[] documents) {
            int i = 0;
            while(i<documents.length){
                if(documents[i]==i){
                    i++;
                    continue;
                }
                if(documents[documents[i]]==documents[i]){//多个元素对应同一个下标
                    return documents[i];
                }
                int temp = documents[i];
                documents[i] = documents[temp];
                documents[temp] = temp;
            }
            return -1;
        }
    }
    时间复杂度:O(n)
    空间复杂度:O(1)
    
    王位詮釋 普通 2024年4月14日 下午9:05

    本打卡对应问题:【杂题】剑指 Offer 62. 圆圈中最后剩下的数字
    具体打卡内容:
    数学+迭代法:
    class Solution {
        public int iceBreakingGame(int num, int target) {
            int x = 0;
            for (int i = 2; i <= num; i++) {
                x = (x + target) % i;
            }
            return x;
        }
    }
    
    链表法,模拟删除,但是后面会超时:
    class Solution {
        public int iceBreakingGame(int num, int target) {
            Node pre = new Node();
            Node cur = pre;
            //构造环形数组
            for(int i=0;i<num;i++){
                cur.next = new Node(i,null);
                cur = cur.next;
            }
            cur.next = pre.next;//现在cur指向的是最后一个元素
            cur = cur.next;//此时cur指向第一个元素
            while(cur.next!=cur){
                int count = 1;
                while(count<target){
                    cur = cur.next;//往后走一步
                    count++;
                }
                //把cur所指向的节点删除
                cur.val = cur.next.val;
                cur.next = cur.next.next;
            }
            return cur.val;
        }
    }
    class Node{
        int val;
        Node next;
        public Node(){
    
        }
        public Node(int val,Node next){
            this.val = val;
            this.next = next;
        }
    }
    
    王位詮釋 普通 2024年4月14日 下午7:48

    本打卡对应问题:【杂题】剑指 Offer 10- II. 青蛙跳台阶问题
    具体打卡内容:
    class Solution {
        public int trainWays(int num) {
            final int MOD = 1000000007;
            if(num==0){
                return 1;
            }
            if(num<=2){
                return num;
            }
            int first = 1;
            int second = 2;
            for(int i=3;i<=num;i++){
                int temp = first+second;
                first = second;
                second = temp%MOD;
            }
            return second;
        }
    }
    思路:小青蛙一次可以跳一阶,也可以跳两阶,所以如果要知道跳num阶有多少中情况,只需要之后num-1或者num-2有多少阶就好了。
    时间复杂度:O(n)
    空间复杂度:O(1)
    
    王位詮釋 普通 2024年4月14日 下午7:44

    本打卡对应问题:【杂题】剑指 Offer 10- I. 斐波那契数列
    具体打卡内容:
    class Solution {
        public int fib(int n) {
            final int MOD = 1000000007;
            if(n<=1){
                return n;
            }
            int first = 0;
            int second = 1;
            for(int i=2;i<=n;i++){
                int temp = first+second;
                first = second;
                second = temp%MOD;
            }
            return second;
        }
    }
    时间复杂度:O(n)
    空间复杂度:O(1)
    需要注意题意里的取模部分,给我恶心坏了
    
    王位詮釋 普通 2024年4月14日 下午6:24

    本打卡对应问题:【动态规划专题】LeetCode 72. 编辑距离
    具体打卡内容:
    class Solution {
        public int minDistance(String word1, String word2) {
            int m = word1.length();
            int n = word2.length();
            //dp[i][j]表示当word1长度为i,word2长度为j的时候
            //需要的最少的操作数
            int[][] dp = new int[m+1][n+1];
            dp[0][0] = 0;
            //初始化第一行
            for(int i=1;i<n+1;i++){
                dp[0][i] = dp[0][i-1]+1;
            }
            //初始化第一列
            for(int i=1;i<m+1;i++){
                dp[i][0] = dp[i-1][0]+1;
            }
            //把word1转换为word2所需要的最少步数
            for(int i=1;i<m+1;i++){
                for(int j=1;j<n+1;j++){
                    if(word1.charAt(i-1)==word2.charAt(j-1)){//i处的字符与j处的字符相等
                        dp[i][j] = dp[i-1][j-1];
                    }else{
                        int add = dp[i][j-1];//插入一个字符之前
                        int delete = dp[i-1][j];//删除一个字符之前
                        int replace = dp[i-1][j-1];//替换一个字符之前
                        dp[i][j] = Math.min(Math.min(add,delete),replace)+1;
                    }
                }
            }
            return dp[m][n];
        }
    }
    思路:用二维数组记录长度为i的字符串word1转换为长度为j的字符串word2所需要的最少的操作数,如果word1的第i个字符和word2的第j个字符相同,则dp[i][j] =  dp[i-1][j-1],否则就需要看是要怎么操作:添加一个字符、删除一个字符、替换一个字符。
    时间复杂度:O(mn)
    空间复杂度:O(mn)
    优化成一维数组:
    class Solution {
        public int minDistance(String word1, String word2) {
            int m = word1.length();
            int n = word2.length();
            int[] dp = new int[n+1];
            //初始化
            for(int i=1;i<n+1;i++){
                dp[i] = dp[i-1]+1;
            }
            for(int i=1;i<m+1;i++){
                int temp = dp[0];
                dp[0] = dp[0]+1;
                for(int j=1;j<n+1;j++){
                    int pre = temp;
                    temp = dp[j];
                    if(word1.charAt(i-1)==word2.charAt(j-1)){//word1第i个字符和word2第j个字符相等
                        dp[j] = pre;
                    }else{
                        dp[j] = Math.min(Math.min(pre,dp[j-1]),dp[j])+1;
                    }
                }
            }
            return dp[n];
        }
    }
    时间复杂度:O(mn)
    空间复杂度:O(n)
    
    王位詮釋 普通 2024年4月14日 下午5:27

    本打卡对应问题:【动态规划专题】LeetCode 174. 地下城游戏
    具体打卡内容:
    class Solution {
        public int calculateMinimumHP(int[][] dungeon) {
            if(dungeon==null||dungeon.length<=0||dungeon[0].length<=0){
                return 0;
            }
            int m = dungeon.length;
            int n = dungeon[0].length;
            //dp[i][j]表示从i,j位置到终点所需要的最少血量
            int[][] dp = new int[m][n];
            //初始值
            //如果dungeon[m-1][m-1]是正值,说明这里会加血,所以初始值不需要设置
            //如果是负值的话,说明这里会减血,所以需要设置初始值
            dp[m-1][n-1] = Math.max(-dungeon[m-1][n-1],0);
            //设置最后一行的值
            for(int i = n-2;i>=0;i--){
                int needMin = dp[m-1][i+1]-dungeon[m-1][i];
                dp[m-1][i] = Math.max(needMin,0);
            }
            //设置最后一列的值
            for(int i=m-2;i>=0;i--){
                int needMin = dp[i+1][n-1]-dungeon[i][n-1];
                dp[i][n-1] = Math.max(needMin,0);
            }
    
            for(int i=m-2;i>=0;i--){
                for(int j = n-2;j>=0;j--){
                    int needMin = Math.min(dp[i][j+1],dp[i+1][j])-dungeon[i][j];
                    dp[i][j] = Math.max(0,needMin);
                }
            }
            return dp[0][0]+1;
        }
    }
    思路:由于这个题在往后便利过程中会涉及到加血,
    所以i,j位置的值可能是和后面的值有关系,不像之前的题那样,
    i,j位置的值只与左或者上的值有关,所以这个题可以从后往前推,
    如果从后往前推,之前的动归思想都是从开始位置到当前位置的xxx,
    而这里的dp[i][j]表示的就是从当前位置到最后所需要的血量。
    这时候前一位置的血量要根据右边和下边的值来判断,
    所需要的最小血量needMin = Math.min(dp[i+1][j],dp[i][j+1]),
    dp[i][j] = Math.max(needMin-dungeon[i][j],0)
    
    Jimmy 普通 2024年4月14日 下午5:24

    本打卡对应问题:【动态规划专题】LeetCode 198. 打家劫舍
    具体打卡内容:

    子问题: dp[i] = max(dp[i-1],dp[i-2]+nums[i-1]);

    class Solution {
    public:
        int rob(vector<int>& nums) {
            if(nums.size() == 0)
            {
                return 0;
            }
            int N = nums.size();
            vector<int> dp(N+1,0);
            dp[0] = 0;
            dp[1] = nums[0];
            for(int i=2;i<=N;i++)
            {
                dp[i] = max(dp[i-1],dp[i-2]+nums[i-1]);
            }
            return dp[N];
        }
    };
    
    王位詮釋 普通 2024年4月14日 下午3:22

    本打卡对应问题:【动态规划专题】LeetCode 322. 零钱兑换
    具体打卡内容:
    这个题我最开始的时候陷入了一个误区:要凑出来面值为amount,而且同时
    硬币数量还得最少,那就从最大面值的硬币开始分配,这样最后结果就会是
    最小的面值,这种想法本身没问题,但是可能会出现这种情况:一直用最大面值
    硬币匹配导致最后剩下的amount值不足以匹配剩余的硬币,所以这种是有问题的
    class Solution {
        public int coinChange(int[] coins, int amount) {
            //dp[i]表示组成金额i所需要的最少的硬币数量
            //前面凑出来的i的最小的硬币数量可以用来凑后面的i的硬币数量
            //由于后面的i的硬币数量需要依赖前面的i的硬币数量,所以后面的i
            //能凑出来的话dp[i]值一定是小于amount+1的,否则就返回-1
            int[] dp = new int[amount+1];
            Arrays.fill(dp,amount+1);
            dp[0] = 0;
            for(int i=1;i<amount+1;i++){
                for(int j=0;j<coins.length;j++){
                    //防止越界,因为i表示金额值,coins[j]表示第j枚硬币的金额值,i不应该小于coins[j]
                    if(coins[j]<=i){
                        dp[i] = Math.min(dp[i],dp[i-coins[j]]+1);
                    }
                }
            }
            return dp[amount]>amount?-1:dp[amount];
        }
    }
    思路:数组dp[i]表示凑出来面值为i时需要的最少的硬币数量;如果面值为i
    的时候前面的都凑不出来,那i的面值肯定也凑不出来,就返回-1;
    否则就动态计算需要的面值,dp[i] = Math.min(dp[i],dp[i-coins[j]]+1),最后返回结果。
    
    幽小皮 永久会员 2024年4月13日 下午8:46

    本打卡对应问题:【作业8】链表专题:用递归合并排序链表
    具体打卡内容:

    打卡

    “`
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
    if(list1 == null){
    return list2;
    }else if(list2 == null){
    return list1;
    }
    if(list1.val <= list2.val){ list1.next = mergeTwoLists(list1.next, list2); return list1; }else{ list2.next = mergeTwoLists(list1, list2.next); return list2; }

    }```java
    
    heathhou 普通 2024年4月13日 下午3:37

    本打卡对应问题:【动态规划专题】LeetCode 322. 零钱兑换
    具体打卡内容:
    class Solution {
    public:
        int coinChange(vector<int>& coins, int amount) {
            if(coins.size() <= 0){
                return 0;
            }
    
            int Max = amount + 1;
            // 定义 dp[i] 为组成金额 i 所需最少的硬币数量
            // 初始值设置为需要 amount + 1 的硬币,这是最大值了
            vector<int> dp(amount + 1, Max); 
    
            dp[0] = 0;
            for(int i = 1; i <= amount; ++i){
                for(int j = 0; j < coins.size(); ++j){
                    if(coins[j] <= i){
                        dp[i] = min(dp[i], dp[i-coins[j]] + 1);
                    }
                }
            }
            return dp[amount] > amount ? -1 : dp[amount];
        }
    };
    
    heathhou 普通 2024年4月13日 下午3:17

    本打卡对应问题:【动态规划专题】LeetCode 198. 打家劫舍
    具体打卡内容:
    class Solution {
    public:
        int rob(vector<int>& nums) {
            if(nums.size() <= 0){
                return 0;
            }
            // 定义数组元素的含义
            // dp[k]: 偷前k间房子的最大金额
            vector<int> dp(nums.size()+1, 0);
    
            // 找出数组元素之间的关系式
            // dp[n] = max(dp[n-1], dp[n-2] + nums[n-1])
    
            // 找出初始值
            dp[0] = 0;
            dp[1] = nums[0];
    
            for(int k = 2; k <= nums.size(); ++k){
                dp[k] = max(dp[k-1], dp[k-2] + nums[k-1]);
            }
    
            return dp[nums.size()];
    
    
    
        }
    };
    
    =.= 普通 2024年4月12日 下午11:05

    本打卡对应问题:【动态规划专题】LeetCode 64. 最小路径和
    具体打卡内容:

    class Solution {
    public int minPathSum(int[][] grid) {
    int m = grid.length;
    int n = grid[0].length;

        int[][] dp = new int[m][n];
        dp[0][0] = grid[0][0];
        for(int j=1; j<n; j++){
            dp[0][j] = dp[0][j-1] + grid[0][j];
        }
        for(int i=1; i<m; i++){
            dp[i][0] = dp[i-1][0] + grid[i][0];
        }
    
        for(int i=1; i<m; i++){
            for(int j=1; j<n; j++){
                dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
            }
        }
        return dp[m-1][n-1];
    }
    

    }

    时间:O(mn)
    空间:O(mn)

    =.= 普通 2024年4月12日 下午10:54

    本打卡对应问题:【动态规划】剑指 Offer 42. 连续子数组的最大和
    具体打卡内容:

    class Solution {
    public int maxSales(int[] sales) {
    int n = sales.length;

        int[] dp = new int[n];
        int ans = sales[0];
        dp[0] = sales[0];
        for(int i=1; i<n; i++){
            dp[i] = Math.max(sales[i], sales[i]+dp[i-1]);
            ans = Math.max(ans, dp[i]);
        }
    
        return ans;
    }
    

    }

    时间:O(n)
    空间:O(n)

    YOLO 普通 2024年4月12日 下午9:39

    本打卡对应问题:【二分查找专题】剑指 Offer 53 – II. 0~n-1中缺失的数字
    具体打卡内容:
    /*一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。
    在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。 */
    class Solution {
        public int takeAttendance(int[] records) {
            int left = 0 , right = records.length - 1;
            while(left < right){
                int mid = (right - left)/2 + left;
                if(records[mid] == mid){
                    left = mid + 1;
                }
                else{
                    right = mid;
                }    
            }
    
            if(records[left] == left){
                    left = left + 1;
            }
            return left;
        }
    }
    
    YOLO 普通 2024年4月12日 下午9:29

    本打卡对应问题:【二分查找专题】剑指 Offer 53 – I. 在排序数组中查找
    具体打卡内容:
    /*统计一个数字在排序数组中出现的次数。 */
    class Solution {
        public int countTarget(int[] scores, int target) {
            //常见题型:
            //1、寻找第一个>=target的数;2、寻找第一个=target的数
            //3、寻找最后一个>=target的数;4、寻找最后一个=target的数
    
            int left = search2(scores , target);
            int right = search4(scores, target);
    
            if(left < 0 || right < 0)  return 0;
            return right - left + 1;
        }
    
        //2、寻找第一个=target的数的下标
        int search2(int[] nums , int target){
            if(nums == null || nums.length <= 0){
                return -1;
            }
            int left = 0,right = nums.length - 1;
            while(left < right){
                //向下取整
                int mid = (right - left)/2 + left;
                if(nums[mid]>=target){
                    right = mid; 
                }
                else{
                    left = mid + 1;
                }
            }
        //判断该数是否存在
        if(nums[left]!=target) return -1;
        return left;
        }
    
        //4、寻找最后一个=target的数的下标
        int search4(int[] nums , int target){
            if(nums == null || nums.length <= 0){
                return -1;
            }
            int left = 0 , right = nums.length -1;
            while(left < right){
                //向上取整
                int mid = (right - left + 1)/2 + left;
                if(nums[mid] <= target){
                    left = mid;
                }
                else{
                    right = mid - 1;
                }
            }
            //判断该数是否存在
            if(nums[left] != target) return -1;
            return left;
        }
    
    }
    
    幽小皮 永久会员 2024年4月12日 下午8:54

    本打卡对应问题:【作业7】字节真题:变形的链表反转
    具体打卡内容:

    “`
    //首先逆序然后使用链表反转
    public ListNode reverseKGroup(ListNode head, int k) {

        ListNode newhead = reverseIn(head);
        ListNode nnhead = reverse(newhead, k);
        return reverseIn(nnhead);
    
    }```java
    
    YOLO 普通 2024年4月12日 下午8:35

    本打卡对应问题:【二分查找专题】给出四种二分查找的模板
    具体打卡内容:
    1、//寻找第一个大于target的元素的下标,案例:arr[1,2,3,3,3,4,5,5,7],target=3
    public static int upper(int[] arr,int target){
        int l = 0;
        int r = arr.length - 1;
        //判断特殊情况
        if(arr[r] <= target){
            return -1;
        }
        //[l,r],在二分查找的过程中,不断缩小我们的查找范围,直到查找范围里面只有一个元素,那个就是我们要找的元素
        while(l < r){
            int mid = (r-l)/2+l;
            if(arr[mid] < target){
                l = mid;
            }
            else if(arr[mid] == target){
                l = mid + 1;
            }
            else{//arr[mid] < target
                l = mid + 1;
            }
        }
        return l;
    }
    2、//若数组中存在等于target的元素,则返回最后一个等于target的元素的下标
    //如果不存在,则返回第一个大于target的元素下标
    //案例:arr[1,2,3,3,3,4,5,5,7],target=3
    public static int floor-upper(int[] arr,int target){
        int l = 0;
        int r = arr.length - 1;
        //判断特殊情况
        if(arr[r] < target){
            return -1;
        }
        //[l,r],在二分查找的过程中,不断缩小我们的查找范围,直到查找范围里面只有一个元素,那个就是我们要找的元素
        while(l < r){
            int mid = (r-l)/2+l;
            if(arr[mid] < target){
                r = mid;
            }
            else if(arr[mid] == target){
                l = mid + 1;
            }
            else{//arr[mid] < target
                l = mid + 1;
            }
        }
        if(l-1 >= 0 && arr[l - 1] == target){
            return l - 1;
        }
    
        return l;
    }
    3、//寻找第一个小于target的元素的下标,案例:arr[1,2,3,3,3,4,5,5,7],target=3
    public static int lower(int[] arr,int target){
        int l = 0;
        int r = arr.length - 1;
        //判断特殊情况
        if(arr[r] >= target){
            return -1;
        }
        //[l,r],在二分查找的过程中,不断缩小我们的查找范围,直到查找范围里面只有一个元素,那个就是我们要找的元素
        while(l < r){
            int mid = (r-l + 1)/2+l;
            if(arr[mid] < target){
                r = mid - 1;
            }
            else if(arr[mid] == target){
                r = mid - 1;
            }
            else{//arr[mid] < target
                l = mid;
            }
        }
        return l;
    }
    4、//若数组中存在等于target的元素,则返回最后一个等于target的元素的下标
    //如果不存在,则返回第一个大于target的元素下标
    //案例:arr[1,2,3,3,3,4,5,5,7],target=3
    public static int floor-lower(int[] arr,int target){
        int l = 0;
        int r = arr.length - 1;
        //判断特殊情况
        if(arr[r] > target){
            return -1;
        }
        //[l,r],在二分查找的过程中,不断缩小我们的查找范围,直到查找范围里面只有一个元素,那个就是我们要找的元素
        while(l < r){
            int mid = (r-l + 1)/2+l;
            if(arr[mid] < target){
                r = mid - 1;
            }
            else if(arr[mid] == target){
                r = mid - 1;
            }
            else{//arr[mid] < target
                l = mid;
            }
        }
        if(l + 1 <= arr.length && arr[l - 1] == target){
            return l + 1;
        }
    
        return l;
    }
    
    紫芝 普通 2024年4月12日 上午9:52

    本打卡对应问题:【杂题】剑指 Offer 29. 顺时针打印矩阵
    具体打卡内容:

    思路:模拟顺时针打印矩阵,需要注意边界情况

    “`c++
    class Solution {
    public:
    vector spiralArray(vector>& array) {
    if (array.empty()) return {};
    int m = array.size(), n = array[0].size();
    vector
    ans(m*n, 0);
    int idx = 0;
    int l = 0, r = n-1, t = 0, b = m-1;
    while (true) {
    // top row: t, j = [l -> r]
    for (int j=l; j<=r; j++) { ans[idx++] = array[t][j]; } // top row is over. if (++t > b) break;
    // right col: i = [t -> b], r
    for (int i=t; i<=b; i++) { ans[idx++] = array[i][r]; } // right col is over. if (--r < l) break; // bottom row: b, j = [r -> l]
    for (int j=r; j>=l; j–) {
    ans[idx++] = array[b][j];
    }
    // bottom row is over.
    if (–b < t) break; // left col: i = [b -> l], l
    for (int i=b; i>=t; i–) {
    ans[idx++] = array[i][l];
    }
    // left col is over.
    if (++l > r) break;
    }
    return ans;
    }
    };
    “`

    紫芝 普通 2024年4月12日 上午9:19

    本打卡对应问题:【杂题】剑指 Offer 62. 圆圈中最后剩下的数字
    具体打卡内容:

    思路:约瑟夫环

    func iceBreakingGame(num int, target int) int {
        old := 0
        for i:=2; i<=num; i++ {
            old = (old + target) % i
        }
        return old
    }
    
    云无深雁影 普通 2024年4月11日 上午12:40

    本打卡对应问题:【动态规划专题】LeetCode 174. 地下城游戏
    具体打卡内容:

    class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
    int[][] dp = new int[dungeon.length][dungeon[0].length];
    dp[dungeon.length-1][dungeon[0].length-1] = 1 + Math.max(0, – dungeon[dungeon.length-1][dungeon[0].length-1]);
    for(int i = dungeon.length – 2; i >= 0; i–){
    dp[i][dungeon[0].length – 1] = Math.max(1,dp[i + 1][dungeon[0].length – 1] – dungeon[i][dungeon[0].length – 1]);
    }
    for(int j = dungeon[0].length – 2; j >= 0; j–){
    dp[dungeon.length – 1][j] = Math.max(1, dp[dungeon.length – 1][j + 1] – dungeon[dungeon.length – 1][j]);
    }

        for(int i = dungeon.length - 2; i >= 0; i--){
            for(int j = dungeon[0].length - 2; j >= 0; j--){
                dp[i][j] = Math.max(1,Math.min(dp[i+1][j],dp[i][j+1]) - dungeon[i][j]);
            }
        }
        return dp[0][0];
    }
    

    }
    //dp
    //空间复杂度On2
    //时间复杂度On2

    云无深雁影 普通 2024年4月10日 下午11:49

    本打卡对应问题:【杂题】剑指 Offer 62. 圆圈中最后剩下的数字
    具体打卡内容:

    class Solution {
    public int iceBreakingGame(int num, int target) {
    List list = new ArrayList<>();
    for(int i = 0; i < num; i++)
    list.add(i);
    int current = 0;
    for(int i = 0; i < num – 1; i++){
    current = (current + target -1) % list.size();
    list.remove(current);
    }
    return list.get(0);
    }
    }//空间On2
    //时间On
    //链表解法

    class Solution {
    public int iceBreakingGame(int num, int target) {
    int ans = 0;
    for(int i = 2; i <= num; i++){
    ans = (ans + target) % i;
    }
    return ans;
    }
    }//数学解法

    云无深雁影 普通 2024年4月10日 下午11:46

    本打卡对应问题:【动态规划专题】剑指 Offer 49. 丑数
    具体打卡内容:

    class Solution {
    public int nthUglyNumber(int n) {
    int[] dp = new int[n];
    int i = 0, j = 0, k = 0;
    dp[0] = 1;
    int current = 1;
    while(current < n){
    int min = Math.min(dp[i] * 2,Math.min(dp[j] * 3,dp[k] * 5));
    dp[current++] = min;
    if(min dp[i] * 2) i++;
    if(min
    dp[j] * 3) j++;
    if(min dp[k] * 5) k++;
    }
    return dp[n-1];

    }
    

    }
    //时间复杂度On 空间复杂度On

    云无深雁影 普通 2024年4月10日 下午11:21

    本打卡对应问题:【动态规划专题】LeetCode 42. 接雨水
    具体打卡内容:

    class Solution {
    public int trap(int[] height) {
    int[] water = new int[height.length];
    int i = 0;
    int ans = 0;
    while(i < height.length){
    int curentHeight = height[i];
    int j = i + 1;
    while(j < height.length){
    if(height[j] < height[i])
    j++;
    else
    break;
    }
    if(j < height.length){
    for(int k = i + 1; k < j; k++ )
    water[k] = height[i];
    }
    i = j ;
    }
    i = height.length – 1;
    while(i >= 0){
    int j = i – 1;
    while(j >= 0){
    if(height[j] < height[i])
    j–;
    else
    break;
    }
    if(j >= 0 ){
    for(int k = i – 1; k > j; k– )
    water[k] = height[i];
    }
    i = j ;
    }
    for(int h = 0; h < height.length; h++)
    ans += Math.max(water[h] – height[h],0);
    return ans;
    }
    }
    //来回两次遍历 时间复杂度On 空间复杂度On

    class Solution {
    public int trap(int[] height) {
    int ans = 0;
    int i = 0;
    int leftMax = height[i];
    int j = height.length – 1;
    int rightMax = height[j];
    while(i < j){
    if(height[i] < height[j]){
    ans += leftMax – height[i];
    i++;
    leftMax = Math.max(leftMax,height[i]);
    }
    else{
    ans += rightMax – height[j];
    j–;
    rightMax = Math.max(rightMax,height[j]);
    }
    }
    return ans;
    }
    }//优化法 空间复杂度降到O1

    白雪公主倒拔垂杨柳 永久会员 2024年4月10日 下午5:33

    本打卡对应问题:【杂题】剑指 Offer 29. 顺时针打印矩阵
    具体打卡内容:
    class Solution {
        public int[] spiralArray(int[][] array) {
            if(array==null || array.length==0 || array[0].length ==0) return new int[0];
    
            //记录可移动的列数的范围
            int l=0;
            int r=array[0].length-1;
            // 记录可移动的行数的范围
            int t = 0;
            int b=array.length-1;
    
            //用于保存结果的数组
            int[] res = new int[(r+1) * (b+1)];
            int index=0;
    
            while(true){
                //→
                for(int i=t,j=l;j<=r;j++) res[index++]=array[i][j];
                if(++t>b) break; //下次→只能从++b行开始了
    
                // ↓
                for(int i=t,j=r;i<=b;i++) res[index++]=array[i][j];
                if(l>--r) break; //下次↓只能从--r列开始了
    
                //←
                for(int i=b,j=r;j>=l;j--) res[index++]=array[i][j];
                if(t>--b) break;//下次→只能从--b行开始了
    
                //↑
                for(int i=b,j=l;i>=t;i--)  res[index++]=array[i][j];
                if(++l>r) break;//下次↑只能从++l列开始了
            }
    
            return res;
        }
    }
    

    时间复杂度:O(nm)
    额外空间复杂度:O(n
    m)

    白雪公主倒拔垂杨柳 永久会员 2024年4月10日 下午4:24

    本打卡对应问题:【杂题】剑指 Offer 10- II. 青蛙跳台阶问题
    具体打卡内容:
    class Solution {
        public int trainWays(int num) {
            if(num<=1) return 1;
            if(num==2) return 2;
            int a=1;
            int b=2;
            int c=0;
            for(int i=3;i<=num;i++){
                c=(a+b)%1000000007;
                a=b;
                b=c;
            }
    
            return c;
        }
    }
    

    //时间复杂度On
    //空间复杂度O1

    白雪公主倒拔垂杨柳 永久会员 2024年4月10日 下午4:23

    本打卡对应问题:【杂题】剑指 Offer 10- I. 斐波那契数列
    具体打卡内容:
    class Solution {
        public int fib(int n) {
            // 特殊情况
            if( n <= 1){
                return n;
            }
    
            // int[] dp = new int[n+1];
    
            // dp[0]=0;
            // dp[1]=1;
            int a =0;
            int b=1;
            int c=0;
    
            // if(n==0) return b;
            // if(n==1) return 1;
    
            for(int i=2;i<=n;i++){
                c=(a+b)%1000000007;
                a=b;
                b=c;
            }
    
            return c;
        }
    }
    
    白雪公主倒拔垂杨柳 永久会员 2024年4月10日 下午3:40

    本打卡对应问题:【杂题】剑指 Offer 04. 二维数组中的查找
    具体打卡内容:
    class Solution {
        public boolean findTargetIn2DPlants(int[][] plants, int target) {
            if(plants ==null || plants.length<=0 || plants[0].length<=0) return false;
            int rows = plants.length;
            int cols = plants[0].length;
    
            // //左下角
            // int row = rows-1;
            // int col = 0;
            // while(row>=0 && col<cols){
            //     if(plants[row][col]<target){
            //         col++;
            //     }else if(plants[row][col]>target){
            //         row--;
            //     }else{
            //         return true;
            //     }
            // }
    
            //试试右上角
            int row = 0;
            int col = cols-1;
            while(row<rows && col>=0){
                if(plants[row][col]<target){
                    row++;
                }else if(plants[row][col]>target){
                    col--;
                }else{
                    return true;
                }
            }
    
            return false;
        }
    }
    

    时间复杂度:O(n+m)
    额外空间复杂度:O(1)

    白雪公主倒拔垂杨柳 永久会员 2024年4月10日 下午3:21

    本打卡对应问题:【杂题】剑指 Offer 03. 数组中重复的数字
    具体打卡内容:
    • 哈希表的方法
    class Solution {
        public int findRepeatDocument(int[] documents) {
    
            Map<Integer, Integer> countMap = new HashMap<>();
    
            for (int document : documents) {
                countMap.put(document, countMap.getOrDefault(document, 0) + 1);
    
                if(countMap.get(document)>1) return document;
            }
    
            return -1;
        }
    }
    

    时间复杂度o(n),空间复杂度o(n)

    • 文件id的范围是0-(n-1),利用这一点,可以采用坐标法
    class Solution {
        public int findRepeatDocument(int[] documents) {
    
            for(int i=0;i<documents.length;i++){
                while(documents[i]!=i){
                    if(documents[i]==documents[documents[i]]) return documents[i];
    
                    int k = documents[documents[i]];
                    documents[documents[i]]=documents[i];
                    documents[i]=k;
                }
            }
    
            return -1;
        }
    }
    

    时间复杂度:O(n)
    额外空间复杂度:O(1)

    开心果🍅 永久会员 2024年4月9日 下午10:03

    本打卡对应问题:【作业11】二叉树层序遍历(变形版)
    具体打卡内容:

    打卡

    “`java
    /**
    * Definition for a binary tree node.
    * public class TreeNode {
    * int val;
    * TreeNode left;
    * TreeNode right;
    * TreeNode() {}
    * TreeNode(int val) { this.val = val; }
    * TreeNode(int val, TreeNode left, TreeNode right) {
    * this.val = val;
    * this.left = left;
    * this.right = right;
    * }
    * }
    */
    class Solution {
    Queue queue = new LinkedList<>();
    List> res = new ArrayList<>();
    public List> decorateRecord(TreeNode root) {
    if(root == null) return new ArrayList>();
    queue.add(root);
    int count =0;
    while(!queue.isEmpty() && root != null){
    count++;
    List
    t = new ArrayList<>();
    int size = queue.size();
    for(int i = 0; i< size; i++){ TreeNode temp = queue.poll(); if(count%2==1){ t.add(temp.val); } if(count%2==0){ t.add(0,temp.val); }

                  if(temp.left != null){
                         queue.add(temp.left);
                  }
                  if(temp.right != null){
                         queue.add(temp.right);
                   }
            }
            res.add(t);
    
        }
    
        return res;
    }
    

    }

    YOLO 普通 2024年4月9日 下午9:53

    本打卡对应问题:【二叉树专题】剑指 Offer 37. 序列化二叉树
    具体打卡内容:
     /*请实现两个函数,分别用来序列化和反序列化二叉树。 */
    public class Codec {
    
        // Encodes a tree to a single string.
        public String serialize(TreeNode root) {
            if(root == null){
                return "";
            }
            //StringBuilder 的特性:利用append拼接八大类型的任一种类型,此时选择以字符串类型进行拼接
            StringBuilder build = new StringBuilder();
            Queue<TreeNode> queue = new LinkedList<>();
            queue.add(root);
    
            while(!queue.isEmpty()){
               TreeNode t = queue.poll();
                if(t != null){
                    queue.add(t.left);
                    queue.add(t.right);
                    build.append(t.val + ",");
                }
                else{
                    build.append("null,");
                }
    
            }
            return build.toString();
    
        }
    
        // Decodes your encoded data to tree.
        public TreeNode deserialize(String data) {
            if(data == null || data.length() <= 0){
                return null;
            }
            String[] s = data.split(",");
            Queue<TreeNode> queue = new LinkedList<>();
            //将字符串的第一位先定义好,并入队列
            TreeNode root = new TreeNode(Integer.parseInt(s[0]));
            queue.add(root);
            int i = 1;
            while(!queue.isEmpty()){
                TreeNode t = queue.poll();
                //构建左子树
                if(!s[i].equals("null")){
                    TreeNode left = new TreeNode(Integer.parseInt(s[i]));
                    t.left = left;
                    queue.add(left);
                }
                i++;
                //构建右子树
                if(!s[i].equals("null")){
                    TreeNode right = new TreeNode(Integer.parseInt(s[i]));
                    t.right = right;
                    queue.add(right);
                }
                i++;
            }
            return root;
    
        }
    }
    时间:On,空间:On
    
    Jimmy 普通 2024年4月9日 下午9:49

    本打卡对应问题:【杂题】剑指 Offer 29. 顺时针打印矩阵
    具体打卡内容:

    死循环中按照右下左上的顺序依次提取元素,每次提取一个元素之后都要判断还能否继续遍历

    class Solution {
    public:
        vector<int> spiralArray(vector<vector<int>>& array) {
            vector<int> ans;
            if(array.size() == 0)return ans;
            int left = 0;
            int right = array[0].size()-1;
            int upper = 0;
            int down = array.size()-1;
            while(true)
            {
                for(int j=left;j<=right;j++)ans.push_back(array[upper][j]);
                if(++upper>down)break;
                for(int i=upper;i<=down;i++)ans.push_back(array[i][right]);
                if(--right<left)break;
                for(int j=right;j>=left;j--)ans.push_back(array[down][j]);
                if(--down < upper)break;
                for(int i=down;i>=upper;i--)ans.push_back(array[i][left]);
                if(++left > right)break;
            }
            return ans;
        }
    };
    
    云无深雁影 普通 2024年4月9日 下午9:11

    本打卡对应问题:【杂题】剑指 Offer 03. 数组中重复的数字
    具体打卡内容:

    class Solution {
    public int findRepeatDocument(int[] documents) {
    int cur = 0;
    while(cur < documents.length){
    if(documents[cur] cur){
    cur++;
    continue;
    }
    if(documents[documents[cur]]
    documents[cur])
    return documents[cur];
    int temp = documents[documents[cur]];
    documents[documents[cur]] = documents[cur];
    documents[cur] = temp;
    }
    return -1;
    }
    }
    //时间复杂度On
    //空间复杂度O1

    云无深雁影 普通 2024年4月9日 下午8:14

    本打卡对应问题:【杂题】剑指 Offer 29. 顺时针打印矩阵
    具体打卡内容:

    class Solution {
    public int[] spiralArray(int[][] array) {
    if(array.length 0)
    return new int[0];
    int[] ans = new int[array.length * array[0].length];
    ans[0] = array[0][0];
    int count = 1;
    int left = 0;
    int right = array[0].length – 1;
    int top = 0;
    int bottom = array.length – 1;
    int direction = 0;//右 下 左 上
    int i = 0, j = 0;
    while(left <= right && top <= bottom ){

            switch(direction){
                case 0:                    
                    if(j + 1 <= right){
                        j++; 
                    }
                    else{
                        direction = 1;
                        top++;
                        continue;
                    }
                    ans[count++] = array[i][j];
                    break;
                case 1:
                    if(i + 1 <= bottom){
                        i++; 
                    }
                    else{
                        direction = 2;
                        right--;
                        continue;
                    }
                    ans[count++] = array[i][j];
                    break;
                case 2:
                    if(j - 1 >= left){
                        j--; 
                    }
                    else{
                        direction = 3;
                        bottom--;
                        continue;
                    }
                    ans[count++] = array[i][j];
                    break;
                case 3:
                    if(i - 1 >= top){
                        i--; 
                    }
                    else{
                        direction = 0;
                        left++;
                        continue;
                    }
                    ans[count++] = array[i][j];
                    break;
    
            }
        }
    
    
        return ans;
    
    
    
    }
    

    }
    //空间复杂度Onm
    时间复杂度Onm

    白雪公主倒拔垂杨柳 永久会员 2024年4月9日 下午8:08

    本打卡对应问题:【杂题】剑指 Offer 62. 圆圈中最后剩下的数字
    具体打卡内容:
    class Solution {
        public int iceBreakingGame(int num, int target) {
            return f(num,target);
    
        }
    
        // 返回值为最后留下的元素的号码
        public int f(int num,int target){
            // 退出递归的条件
            if(num==1) return 0;
    
            // 关系:长度为num的序列删除了一个后成为长度为 num -1的序列
    
            int x = f(num-1,target);
    
             return (target + x) % num;
        }
    }
    

    时间复杂度:O(num)

    空间复杂度:O(num)

    YOLO 普通 2024年4月9日 下午7:16

    本打卡对应问题:【二叉树专题】剑指 Offer 68 – I. 二叉搜索树的最近公共祖先
    具体打卡内容:
    /*给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先 */
    class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            if(root == null){
                return null;
            }
            while(root != null){
                if(root.val < p.val && root.val < q.val){
                    root = root.right;
                }
                if(root.val > p.val && root.val > q.val){
                    root = root.left;
                }
                else{
                    return root;
                }
    
            }
           return null; 
        }
    }
    
    白雪公主倒拔垂杨柳 永久会员 2024年4月9日 下午6:52

    本打卡对应问题:【动态规划专题】LeetCode 72. 编辑距离
    具体打卡内容:
    class Solution {
        public int minDistance(String word1, String word2) {
            int n1 = word1.length();
            int n2 = word2.length();
    
            int[][] dp = new int[n1+1][n2+1];
    
    
            // 初始化
            for(int i = 0; i <= n1; i++){
                dp[i][0] = i;
            }
            for(int j = 0; j <= n2; j++){
                dp[0][j] = j;
            }
    
            for(int i = 1; i <= n1; i++){
                for(int j = 1; j <= n2; j++){
                    if(word1.charAt(i-1) != word2.charAt(j-1)){
                        dp[i][j] =Math.min(Math.min(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]) + 1;
                    }
                    else{
                        dp[i][j]=dp[i-1][j-1];
                    }
    
                }
            }
    
            return dp[n1][n2];
        }
    }