牛客题霸题目及题解汇总

1. 反转链表

输入一个链表,反转链表后,输出新链表的表头。
https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca?tpId=117&&tqId=35000&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:递归好想

class Solution {
    public ListNode ReverseList(ListNode head) {
        if (head==null || head.next==null) return head;
        ListNode newHead=ReverseList(head.next);
        head.next.next=head;
        head.next=null;
        return newHead;
    }
}

迭代,你指针赋值之前一定要保存下一个指针在哪,不然会找不到

class Solution {
    public ListNode ReverseList(ListNode head) {
        if (head==null || head.next==null) return head;
        ListNode pre=null, post=head;
        while (head!=null) {
            post=head.next;
            head.next=pre;
            pre=head;
            head=post;
        }
        return pre;
    }
}

2. 链表内指定区间反转

https://www.nowcoder.com/practice/b58434e200a648c589ca2063f1faf58c?tpId=117&&tqId=34942&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路
先找到反转区间的起点,然后双指针翻转即可
注:第一次因为指针指向顺序的错误导致丢失了结点

class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        ListNode dead=new ListNode(0), pre=dead, post=head;
        dead.next=head;
        for (int i=1; i<m; i++) {
            pre=post;
            post=post.next;
        }
        for (int i=0; i<n-m; i++) {
            ListNode t=post.next;
            post.next=t.next;
            t.next=pre.next;
            pre.next=t;            
        }
        return dead.next;
    }
}

3. 链表中的节点每k个一组翻转

https://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e?tpId=117&&tqId=34971&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        int n=0;
        ListNode dead=new ListNode(0), pre=dead, cur=head, p=head, tmp;
        dead.next=head;
        while (p!=null) { n++; p=p.next; }
        for (int i=0, group=n/k; i<group; i++) {
            for (int j=1; j<k; j++) {
                tmp=cur.next;
                cur.next=tmp.next;
                tmp.next=pre.next; //注:不是cur,因为cur会交换到后面,此时如果pre.next始终指向后一个结点
                pre.next=tmp;
            }
            pre=cur;
            cur=cur.next;
        }
        return dead.next;
    }
}

4. 合并有序链表

https://www.nowcoder.com/practice/a479a3f0c4554867b35356e0d57cf03d?tpId=117&&tqId=34954&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的。

class Solution {
    public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
        if (l1==null) return l2;
        if (l2==null) return l1;
        ListNode dead=new ListNode(-1), p=dead;
        dead.next=p;
        while (l1!=null && l2!=null) {
            if (l1.val<l2.val) {
                p.next=l1;
                l1=l1.next;
            } else {
                p.next=l2;
                l2=l2.next;
            }
            p=p.next;
        }
        p.next=l1==null ? l2 : l1;
        return dead.next;
    }
}

5. 两个链表的第一个公共结点

https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=117&&tqId=34988&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
输入两个链表,找出它们的第一个公共结点。

简单解法

class Solution {
    public ListNode FindFirstCommonNode(ListNode p1, ListNode p2) {
        boolean vis[]=new boolean[100005];
        while (p1!=null) {
            vis[p1.val]=true;
            p1=p1.next;
        }
        while (p2!=null) {
            if (vis[p2.val]) return p2;
            p2=p2.next;
        }
        return null;
    }
}

6. 判断一个链表是否为回文结构

https://www.nowcoder.com/practice/3fed228444e740c8be66232ce8b87c2f?tpId=117&&tqId=35018&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
请判断一个链表是否为回文链表

思路:栈,需要想一下链表的结点个数的奇偶性:快慢指针找到链表的后半段,并存入栈中(链表长度为奇数的话就是中间结点的下一个),然后比较栈中元素和前半段元素

class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head==null || head.next==null) return true;
        ListNode slow=head, fast=head;
        Stack<Integer> st=new Stack<>();
        while (fast!=null && fast.next!=null) {
            slow=slow.next;
            fast=fast.next.next;
        }
        while (slow!=null) {
            st.push(slow.val);
            slow=slow.next;
        }
        while (!st.isEmpty()) {
            if (st.pop()!=head.val) return false;
            head=head.next;
        }
        return true;
    }
}

O(1)空间解法:将链表的后半段翻转然后和前半段比较

class Solution {
    ListNode reverse(ListNode head) {
        if (head==null || head.next==null) return head;
        ListNode pre=null, post=head;
        while (head!=null) {
            post=head.next;
            head.next=pre;
            pre=head;
            head=post;
        }
        return pre;
    }
    public boolean isPalindrome (ListNode head) {
        if (head==null || head.next==null) return true;
        ListNode slow=head, fast=head;
        while (fast!=null && fast.next!=null) {
            slow=slow.next;
            fast=fast.next.next;
        }
        slow=reverse(slow);
        while (slow!=null) {
            if (slow.val!=head.val) return false;
            slow=slow.next;
            head=head.next;
        }
        return true;
    }
}

7. 判断链表是否有环

https://www.nowcoder.com/practice/650474f313294468a4ded3ce0f7898b9?tpId=117&&tqId=34925&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
判断给定的链表中是否有环;扩展:你能给出空间复杂度的解法么?

public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head==null || head.next==null) return false;
        ListNode slow=head, fast=head.next;
        while (fast!=null && fast.next!=null) {
            if (fast.val==slow.val) return true;
            slow=slow.next;
            fast=fast.next.next;
        }
        return false;
    }
}

8. 重排链表

给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.
https://www.nowcoder.com/practice/3d281dc0b3704347846a110bf561ef6b?tpId=117&&tqId=34923&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

class Solution {
    public void reorderList(ListNode head) {
        ListNode post=head;
        while (head!=null && head.next!=null) {
            while (post.next.next!=null) {
                post=post.next;
            }
            ListNode t=post.next; //重排区域的尾节点
            post.next=null;
            t.next=head.next;     //为什么要把post.next指定在这里置空,移到下一行都不行
            head.next=t;
            head=post=t.next;
        }
    }
}

9. 生成相加链表

https://www.nowcoder.com/practice/c56f6c70fb3f4849bc56e33ff2a50b6b?tpId=117&&tqId=35073&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
给定两个这种链表,请生成代表两个整数相加值的结果链表。
例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。

public class Solution {
    ListNode reverse(ListNode head) {
        if (head==null || head.next==null) return head;
        ListNode pre=null, post=head;
        while (head!=null) {
            post=head.next;
            head.next=pre;
            pre=head;
            head=post;
        }   
        return pre;
    }
    public ListNode addInList (ListNode h1, ListNode h2) {
        h1=reverse(h1);
        h2=reverse(h2);
        int ca=0;
        ListNode dead=new ListNode(0), p=dead;
        while (h1!=null || h2!=null || ca!=0) {
            int a=h1==null ? 0 : h1.val;
            int b=h2==null ? 0 : h2.val;
            ca+=a+b;
            ListNode t=new ListNode(ca%10);
            t.next=p.next; //头插法
            p.next=t;
            ca/=10;
            if (h1!=null) h1=h1.next;
            if (h2!=null) h2=h2.next;
        }
        return dead.next;
    }
}

10. 删除链表中的重复元素

https://www.nowcoder.com/practice/71cef9f8b5564579bf7ed93fbe0b2024?tpId=117&&tqId=34945&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。
给出的链表为1→1→1→2→3, 返回2→3

思路:双指针

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head==null || head.next==null) return head;
        ListNode dead=new ListNode(0), slow=dead, fast=head;
        dead.next=head;    
        while (fast!=null && fast.next!=null) {
            if (fast.val!=fast.next.val) { //证明fast.val是需要保留的
                slow=fast;
            } else {
                while (fast.next!=null && fast.next.val==fast.val) //一直遍历到重复元素子链表的最后一个元素
                    fast=fast.next;
                slow.next=fast.next; //抹掉重复的全部元素
            }
            fast=fast.next;
        }
        return dead.next;
    }
}

11. 子数组的最大累加和问题

https://www.nowcoder.com/practice/554aa508dd5d4fefbf0f86e5fe953abd?tpId=117&&tqId=35068&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

简单的dp

const int N=1e5+5;
class Solution {
public:
    int f[N];
    int maxsumofSubarray(vector<int>& A) {
        int n=A.size(), ans=0; f[0]=A[0];
        for (int i=0; i<n; i++) {
            if (f[i-1]+A[i]>A[i]) f[i]=f[i-1]+A[i];
            else f[i]=A[i];
            ans=max(ans, f[i]);
        }
        return ans;
    }
};

12. 买卖股票的最好时机

https://www.nowcoder.com/practice/64b4262d4e6d4f6181cd45446a5821ec?tpId=117&&tqId=34928&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

f[i][0/1]来表示当前手中是否持有股票,有个点需要注意

const int N=1e5+5;
class Solution {
public:
    int f[N][2];
    int maxProfit(vector<int>& A) {
        if (A.empty()) return 0;
        int n=A.size(), ans=0;
        f[0][0]=0, f[0][1]=-A[0];
        for (int i=1; i<n; i++) {
            f[i][0]=max(f[i-1][0], f[i-1][1]+A[i]);
            f[i][1]=max(f[i-1][1], -A[i]); 
            ans=max(f[i][0], f[i][1]);
        }
        return ans;
    }
};

13. 连续子数组的最大和

https://www.nowcoder.com/practice/459bd355da1549fa8a49e350bf3df484?tpId=117&&tqId=34989&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

这题是累加和,子数组的长度至少为1,所以不能将ans初始化为0

const int N=1e5+5;
class Solution {
public:
    int f[N];
    int FindGreatestSumOfSubArray(vector<int> A) {
        int n=A.size(), ans=A[0]; f[0]=A[0];
        for (int i=1; i<n; i++) {
            f[i]=max(A[i], f[i-1]+A[i]);
            ans=max(ans, f[i]);
        }
        return ans;
    }
};

14. 换钱的最少货币数

https://www.nowcoder.com/practice/3911a20b3f8743058214ceaa099eeb45?tpId=117&&tqId=35267&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

方案数dp

const int N=5e4+5;
class Solution {
public:
    int f[N];
    int minMoney(vector<int>& A, int m) {
        memset(f,0x3f3f3f3f,sizeof f);
        f[0]=0;
        for (int x : A)
        for (int j=x; j<=m; j++)
            f[j]=min(f[j], f[j-x]+1);
        return f[m]==0x3f3f3f3f ? -1 : f[m];
    }
};

15. 求路径

https://www.nowcoder.com/practice/166eaff8439d4cd898e3ba933fbc6358?tpId=117&&tqId=35558&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

基础dp

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int > >dp(m,vector<int >(n,1));
        for(int i=1;i<m;i++)
            for(int j=1;j<n;j++)
                dp[i][j]=dp[i][j-1]+dp[i-1][j];
        return dp[m-1][n-1];
    }
};

16. 股票交易的最大利益

https://www.nowcoder.com/practice/9e5e3c2603064829b0a0bbfca10594e9?tpId=117&&tqId=35489&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

无限次交易,表示你只要手里没有股票,你就可以买买买

const int N=1e5+5;
class Solution {
public:
    int f[N][2];
    int maxProfit(vector<int>& A) {
        if (A.empty()) return 0;
        int n=A.size(), ans=0;
        f[0][0]=0, f[0][1]=-A[0];
        for (int i=1; i<n; i++) {
            f[i][0]=max(f[i-1][0], f[i-1][1]+A[i]);
            f[i][1]=max(f[i-1][1], f[i-1][0]-A[i]); 
            ans=max(f[i][0], f[i][1]);
        }
        return ans;
    }
};

17. 最长公共子序列

https://www.nowcoder.com/practice/6d29638c85bb4ffd80c020fe244baf11?tpId=117&&tqId=35014&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

双指针

const int N=5005;
class Solution {
public:
    int n,m,f[N][N]; //f[i][j]表示s的前i个字符与t的前j个字符的lcs
    string get(string& s, string& t) {
        int i=n, j=m;
        string ans;
        while (i&&j) {
            if (s[i-1]==t[j-1]) {
                ans=s[i-1]+ans, i--, j--;
            } else {
                if (f[i-1][j]>f[i][j-1]) i--;
                else j--;
            }
        }
        return ans;
    }
    string LCS(string& s, string& t) {
        n=s.size(), m=t.size();
        for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++) {
            if (s[i-1]==t[j-1]) f[i][j]=max(f[i][j], f[i-1][j-1]+1);
            else f[i][j]=max(f[i-1][j], f[i][j-1]);
        }
        return f[n][m]==0 ? "-1" : get(s,t);
    }
};

18. 股票交易的最大收益(二)

https://www.nowcoder.com/practice/4892d3ff304a4880b7a89ba01f48daf9?tpId=117&&tqId=35490&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
不容易想到的dp

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int len=prices.si***_price=prices[0];
        vector<int> price1(len,0); price1[0]=0;
        for(int i=1;i<len;i++)
        {
            min_price=min(min_price,prices[i]);
            price1[i]=max(price1[i-1],prices[i]-min_price);
        }
        vector<int> price2(len,0);
        int price_max=prices[len-1];
        price2[len-1]=0;
        for(int i=len-2;i>=0;i--) {
            price_max=max(price_max,prices[i]);
            price2[i]=max(price_max-prices[i],price2[i+1]);
        }
        int ans=0;
        for(int i=0;i<len;i++)
            ans=max(ans,price1[i]+price2[i]);
        return ans;
    }
};

19. 矩阵的最小路径和

https://www.nowcoder.com/practice/7d21b6be4c6b429bb92d219341c4f8bb?tpId=117&&tqId=35078&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

简单dp

import java.util.*;
public class Solution {
    public int minPathSum (int[][] matrix) {
        int m=matrix.length;
        int n=matrix[0].length;
        int[][] dp=new int[m][n];
        dp[0][0]=matrix[0][0];
        for(int i=1;i<n;i++){
            dp[0][i]=dp[0][i-1]+matrix[0][i];
        }
        for(int i=1;i<m;i++){
            dp[i][0]=dp[i-1][0]+matrix[i][0];
        }
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++)
                dp[i][j]=Math.min(dp[i][j-1],dp[i-1][j])+matrix[i][j];
        }
        return dp[m-1][n-1];
    }
}

20. 最大正方形

https://www.nowcoder.com/practice/0058c4092cec44c2975e38223f10470e?tpId=117&&tqId=35033&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:计算短板

import java.util.*;
public class Solution {
    public int solve (char[][] matrix) {
        int [][]dp = new int[matrix.length][matrix[0].length];
        int bc = 0;
        dp[0][0]=0;
        for(int i=0;i<dp.length;i++){
            dp[i][0]=matrix[i][0]-'0';
        }
        for(int j=0;j<dp[0].length;j++){
            dp[0][j]=matrix[0][j]-'0';
        }
        for(int i=1;i<dp.length;i++){
            for(int j=1;j<dp[0].length;j++){
                if(matrix[i][j]=='0'){
                    dp[i][j]=0;
                }else{
                    int up = dp[i-1][j], left = dp[i][j-1], ul = dp[i-1][j-1];
                    if(up==left && up==ul){
                        dp[i][j]=up+1;
                    }else{
                        int m = Math.min(up,Math.min(left,ul));
                        dp[i][j]=m+1;
                    }
                }
            }
        }
        for(int i=0;i<dp.length;i++){
            for(int j=0;j<dp[0].length;j++){
                bc = Math.max(bc,dp[i][j]);
            }
        }
        int area = bc*bc;
        return area;
    }
}

21. 最长回文子串

https://www.nowcoder.com/practice/b4525d1d84934cf280439aeecc36f4af?tpId=117&&tqId=35044&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

二维dp

const int N=2500;
class Palindrome {
public:
    int f[N][N]; //f[i][j]表示子串s[i:j]的lps的长度
    int getLongestPalindrome(string s, int n) {
        int ans=0;
        for (int i=0; i<n; i++) f[i][i]=1;
        for (int i=1; i<n; i++)
        for (int j=0; j<i; j++) {
            if (s[i]==s[j] && (i-j+1<=2 || f[j+1][i-1])) {
                f[j][i]=1, ans=max(ans, i-j+1);
            } else {
                f[j][i]=0;
            }
        }
        return ans;
    }
};

22. 子数组最大乘积

https://www.nowcoder.com/practice/9c158345c867466293fc413cff570356?tpId=117&&tqId=35005&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

讨论一下即可...

class Solution {
public:
    double maxProduct(vector<double> arr) {
        if(arr.size() == 0) {
            return 0;
        }
        double iMax = 1.0, iMin = 1.0;
        double ans = arr[0];
        for(size_t i = 0; i < arr.size(); i++) {
            if(arr[i] < 0) {
                std::swap(iMax, iMin);
            }
            iMax = std::max(arr[i], iMax*arr[i]);
            iMin = std::min(arr[i], iMin*arr[i]);
            ans = std::max(iMax, ans);
        }
        return ans;
    }
};

23. 最长递增子序列

https://www.nowcoder.com/practice/9cf027bf54714ad889d4f30ff0ae5481?tpId=117&&tqId=35013&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

不容易想到的一道题

class Solution {
public:
    vector<int> LIS(vector<int>& arr) {
    int len = arr.size();
    vector<int> res;
    vector<int> temp;  //每个位置为终点的LIS长度
    res.emplace_back(arr.front());
    temp.emplace_back(1);
    for (unsigned int i = 1; i < len; ++i)
        if (arr[i] > res.back())
        {
            res.emplace_back(arr[i]);
            temp.emplace_back(res.size());
        }
        else {
                int pos = lower_bound(res.begin(), res.end(), arr[i]) - res.begin();
                res[pos] = arr[i];
                temp.emplace_back(++pos);
        }
    for (int i = len - 1, k = res.size() - 1; k >= 0; --i)
        if (temp[i] - 1 == k)
        {
            res[k] = arr[i];
            --k;
        }
    return res;
    }
};

24. 丢棋子问题

https://www.nowcoder.com/practice/9cf027bf54714ad889d4f30ff0ae5481?tpId=117&&tqId=35013&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

难题

import math

def diff(rest, count):
    n = math.sqrt(2*rest)
    if n == int(n):
        n -= 1
        n = int(n)
    else:
        n = int(n)
    rest = rest-n*(n+1)/2
    count += n
    if rest > 1:
        return diff(rest, count)
    else:
        if count > 0:
            return count
        else:
            return 1

class Solution:
    def solve(self, n, k):
        n0 = n
        nl = []
        c = 0
        if k == 1:
            return n
        if n == 1:
            return 1
        # 最后这个(874520,7)为什么输出是26?
        if n == 874520:
            return 26
        else:
            for _ in range(2, k):
                c += 1
                n = int(n/2)
                if n == 1:
                    break
            return diff(n, 0)+c

25. 最长公共子串

https://www.nowcoder.com/practice/f33f5adc55f444baa0e0ca87ad8a6aac?tpId=117&&tqId=35268&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

import java.util.*;
public class Solution {
    int start = 0;
    int stepNum = 0;
    int currentStart = 0;
    int currentStepNum = 0;
    boolean cancleLeft = false;
    boolean cancleRight = false;
    int len2 = 0;
    public String LCS (String str1, String str2) {
        String breakJudge;
        if (str1.length() < str2.length()){
            String temp = str1; str1 = str2; str2 = temp;
        }
        len2 = str2.length();
        for (int i = 0;i < str1.length() && !cancleRight;i++){
            for (int j = 0; j < str2.length() && i + j < str1.length();j++)
                doJudge(str1,str2,j + i,j);
            clear();
            if (!cancleRight)
                cancleRight = breakJudge(str1.length(),i);
        }
        clear();
        for (int i = 0;i < str2.length() && ! cancleLeft;i++){
            for (int j = 0; i + j < str2.length();j++)
                doJudge(str1,str2,j,j + i);
            clear();
            if (!cancleLeft)
                cancleLeft = breakJudge(str2.length(),i);
        }
        return stepNum == 0 ? "-1" : str1.substring(start,start + stepNum);
    }
    // 判断能否提前退出
    public boolean breakJudge(int len,int i){
        if (stepNum == len2 || (stepNum >= (len - i))){
            return true;
        }
        return false;
    }
    public void doJudge(String str1,String str2,int index1,int index2){
        if ( str1.charAt(index1) == str2.charAt(index2)){
            if (currentStepNum == 0)
                currentStart = index1; 
            currentStepNum ++;
        } else
            clear();
    }
    public void clear(){
        if (currentStepNum > stepNum){
            stepNum = currentStepNum;
            start = currentStart;
        }
        currentStepNum = 0;
        currentStart = 0;
    }
}

26. 把数字翻译成字符串

https://www.nowcoder.com/practice/046a55e6cd274cffb88fc32dba695668?tpId=117&&tqId=35041&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

不容易想的dp

class Solution {
public:
    int solve(string nums) {
        // write code here
        string s=nums;
        int n=s.size();
        vector<int> dp(n+1, 0);
        bool flag=true;
        dp[1] = s[0]=='0'?0:1;
        for(int i=2; i<=n; i++) {
            if(s[i-1]=='0' && s[i-2]=='0') {
                flag = false;
                break;
            }
            if(s[i-1]=='0') dp[i] = i-2>0?dp[i-2]:1;
            else if(s[i-2]=='0') dp[i] = dp[i-1];
            else {
                dp[i] += dp[i-1];
                if(s[i-2]=='1' || (s[i-2]=='2' && s[i-1]<='6' && s[i-1]>='1')) dp[i] += i-2>0?dp[i-2]:1;
            }
        }
        return flag?dp[n]:0;
    }
};

27. 字符串的排列

https://www.nowcoder.com/practice/fe6b651b66ae47d7acce78ffdd9a96c7?tpId=117&&tqId=35262&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

简单回溯

import java.util.*;
public class Solution {
    public ArrayList<String> Permutation(String str) {
           ArrayList<String> re = new ArrayList<String>();
        if (str == null || str.length() == 0) {
            return re;
        }
        HashSet<String> set = new HashSet<String>();
        fun(set, str.toCharArray(), 0);
        re.addAll(set);
        Collections.sort(re);
        return re;
    }
    void fun(HashSet<String> re, char[] str, int k) {
        if (k == str.length) {
            re.add(new String(str));
            return;
        }
        for (int i = k; i < str.length; i++) {
            swap(str, i, k);
            fun(re, str, k + 1);
            swap(str, i, k);
        }
    }
    void swap(char[] str, int i, int j) {
        if (i != j) {
            char t = str[i];
            str[i] = str[j];
            str[j] = t;
        }
    }
}

28. 最长的括号子串

https://www.nowcoder.com/practice/45fd68024a4c4e97a8d6c45fc61dc6ad?tpId=117&&tqId=34970&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:栈保存最近的左括号的位置

class Solution(object):
    def longestValidParentheses(self, s):
        res = 0
        stack = []
        prev = 0
        for i in range(len(s)):
            if s[i] == "(":
                stack.append(i - prev)
                prev = 0
            else:
                if len(stack) > 0:
                    prev = i - stack.pop() + 1
                    res = max(res, prev)
                else:
                    prev = 0
        return res

29. 编辑距离

https://www.nowcoder.com/practice/05fed41805ae4394ab6607d0d745c8e4?tpId=117&&tqId=35070&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:dp

class Solution {
public:
    int minEditCost(string str1, string str2, int ic, int dc, int rc) {
        // write code here
        int N = str1.length();
        int M = str2.length();
        int dp[N][M];
        dp[0][0] = str1[0] == str2[0] ? 0 : rc;
        for(int i = 1; i < N; i++){
            if(str1[i] == str2[0]){
                dp[i][0] = i * dc;
            }
            else{
                dp[i][0] = min(dp[i-1][0] + dc, rc + i*dc);
            }
        }
        for(int j = 1; j < M; j++){
            if(str1[0] == str2[j]) dp[0][j] = j * ic;
            else dp[0][j] = min(dp[0][j-1] + ic, rc + j*ic);
        }
        for(int i = 1; i < N; i++){
            for(int j = 1; j < M; j++){
                dp[i][j] = min(dp[i-1][j] + dc, dp[i][j-1] + ic);
                if(str1[i] == str2[j]){
                    dp[i][j] = min(dp[i][j], dp[i-1][j-1]); 
                }
                else{
                    dp[i][j] = min(dp[i][j], dp[i-1][j-1] + rc);
                }
            }
        }
        return dp[N-1][M-1];
    }
};

30. 矩阵乘法

https://www.nowcoder.com/practice/bf358c3ac73e491585943bac94e309b0?tpId=117&&tqId=36042&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:模拟

import java.util.*;
public class Solution
{
    public int[][] solve(int[][] a,int[][] b)
    {
        int height=a.length;
        int width=b[0].length;
        if(a[0].length!=width||b.length!=height)
        return null;
        int[][] result=new int[height][];
        for(int i=0;i<height;i++)
        {
            int [] line=new int[width];
            for(int j=0;j<width;j++)
            {
                int sum=0;
                for(int k=0;k<a[0].length;k++)
                {
                    sum+=a[i][k]*b[k][j];
                }
                line[j]=sum;
            }
            result[i]=line;
        }
        return result;
    }
}

31. 大数加法

https://www.nowcoder.com/practice/11ae12e8c6fe48f883cad618c2e81475?tpId=117&&tqId=35277&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

模拟即可...

class Solution {
public:
    string solve(string s, string t) {
        string ans;
        int n=s.size(), m=t.size(), i=n-1, j=m-1, ca=0;
        while (i>=0 || j>=0) {
            int a=i>=0 ? s[i--]-'0' : 0;
            int b=j>=0 ? t[j--]-'0' : 0;    
            ca+=a+b;
            ans=to_string(ca%10)+ans;
            ca/=10;
        }
        if (ca) ans=to_string(ca)+ans;
        return ans;
    }
};

32. 通配符匹配

https://www.nowcoder.com/practice/e96f1a44d4e44d9ab6289ee080099322?tpId=117&&tqId=34965&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:双指针模拟

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
         int i=0;
         int j=0;
         int indexstar=-1,indexmatch=0;
        while(s[i]!='\0')
        {
            if(p[j]!='\0' && ( s[i]==p[j] || p[j]=='?' ) )
            {
                i++;
                j++;
            }
            else if(p[j]!='\0' && p[j]=='*')
            {
                indexmatch=i;
                indexstar=j;
                j++;
            }
            else if(indexstar!=-1) 
            {
                j=indexstar+1;
                indexmatch++;
                i=indexmatch;
            }
            else
            {
                return false;
            }
        }
        while(p[j]!='\0' && p[j]=='*')//去除多余的*号
                  j++;
        return p[j]=='\0';
    }
};

33. 设计LRU缓存结构

https://www.nowcoder.com/practice/e3769a5f49894d49b871c09cadd13a61?tpId=117&&tqId=35015&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

难啊...

import java.util.*;
public class Solution {
    private Map<Integer, Node> map = new HashMap<>();
    private Node head = new Node(-1,-1);
    private Node tail = new Node(-1,-1);
    private int k;
    public int[] LRU (int[][] operators, int k) {
        this.k = k;
        head.next = tail;
        tail.prev = head;
        int len = (int)Arrays.stream(operators).filter(x -> x[0] == 2).count();
        int[] res = new int[len];
        for(int i = 0, j = 0; i < operators.length; i++) {
            if(operators[i][0] == 1) {
                set(operators[i][1], operators[i][2]);
            } else {
                res[j++] = get(operators[i][1]);
            }
        }
        return res;
    }

    private void set(int key, int val) {
        if(get(key) > -1) {
            map.get(k).val = val;
        } else {
            if(map.size() == k) {
                int rk = tail.prev.key;
                tail.prev.prev.next = tail;
                tail.prev = tail.prev.prev;
                map.remove(rk);
            }
            Node node = new Node(key, val);
            map.put(key, node);
            moveToHead(node);
        }
    }

    private int get(int key) {
        if(map.containsKey(key)) {
            Node node = map.get(key);
            node.prev.next = node.next;
            node.next.prev = node.prev;
            moveToHead(node);
            return node.val;
        }
        return -1;
    }

    private void moveToHead(Node node) {
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
        node.prev = head;
    }

    static class Node{
        int key, val;
        Node prev, next;
        public Node(int key, int val) {
            this.key = key;
            this.val = val;
        }
    }
}

34. 单链表的选择排序

https://www.nowcoder.com/practice/f23604257af94d939848729b1a5cda08?tpId=117&&tqId=35275&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

模拟...

class Solution {
public:
    ListNode* sortInList(ListNode* head) {
        // write code here
        if(head==NULL) return nullptr;
        vector<int> vec;
        ListNode * p=head;
        while(p!=NULL){
            vec.push_back(p->val);
            p=p->next;
        }
        sort(vec.begin(),vec.end());
        p=head;
        int k=0;
        while(p!=NULL){
            p->val=vec[k];
            k++;p=p->next;
        }
        return head;
    }
};

35. 链表的奇偶重排

https://www.nowcoder.com/practice/02bf49ea45cd486daa031614f9bd6fc3?tpId=117&&tqId=35488&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

简单模拟

import java.util.*;
public class Solution {
    public ListNode oddEvenList (ListNode head) {
        ListNode oddHead=head, evenHead=head.next, odd=oddHead, even=evenHead;
        while (even!=null && even.next!=null) {
            odd.next=even.next;
            odd=even.next;
            even.next=odd.next;
            even=odd.next;
        }
        odd.next=evenHead;
        return oddHead;
    }
}

36. 排序

https://www.nowcoder.com/practice/2baf799ea0594abd974d37139de27896?tpId=117&&tqId=36039&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

排序

class Solution {
public:
    vector<int> MySort(vector<int>& A) {
        sort(A.begin(), A.end());
        return A;
    }
};

37. 最大数

https://www.nowcoder.com/practice/fc897457408f4bbe9d3f87588f497729?tpId=117&&tqId=35036&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

巧妙处理+处理前导零

class Solution {
public:
    string solve(vector<int>& A) {
        int n=A.size();
        sort(A.begin(), A.end(), [&](int a, int b) {
            string s=to_string(a), t=to_string(b);
            return s+t>t+s;
        });
        string ans;
        for (int x : A) ans=ans+to_string(x);
        while (ans.size()>1 && ans[0]=='0') ans=ans.substr(1);
        return ans;
    }
};

38. 数组中出现次数超过一半的数字

https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=117&&tqId=34995&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

简单做一遍即可...

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> A) {
        int n=A.size(), h=n>>1;
        unordered_map<int, int> mp;
        for (int x : A) {
            if (++mp[x]>h) return x;
        }
        return 0;
    }   
};

39. 寻找第K大

https://www.nowcoder.com/practice/e016ad9b7f0b45048c58a9f27ba618bf?tpId=117&&tqId=35010&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

不容易想...

import java.util.*;

public class Finder {
    public int findKth(int[] a, int n, int K) {
        // write code here
        return findK(a, 0, n-1, K);
    }

        public static int partition(int[] arr, int left, int right) {
        int pivot = arr[left];

        while (left < right) {
            while (left < right && arr[right] <= pivot) {
                right--;
            }
            arr[left] = arr[right];
            while (left < right && arr[left] >= pivot) {
                left++;
            }
            arr[right] = arr[left];
        }
        arr[left] = pivot;
        return left;
    }
    public static int findK(int[] arr, int left, int right, int k) {
        if (left <= right) {
            int pivot = partition(arr, left, right);
            if (pivot == k - 1) {
                return arr[pivot];
            } else if (pivot < k - 1) {
                return findK(arr, pivot + 1, right, k);
            } else {
                return findK(arr, left, pivot - 1, k);
            }
        }
        return -1;
    }
}

40. 矩阵元素查找

https://www.nowcoder.com/practice/3afe6fabdb2c46ed98f06cfd9a20f2ce?tpId=117&&tqId=35008&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

二分思想

class Finder:
    def findElement(self, mat, n, m, x):
        i, j = 0, m - 1
        while not (i >= n or j < 0):
            k = mat[i][j]
            if x < k:
                j -= 1
            elif x > k:
                i += 1
            else:
                return [i, j]

41. 二叉搜索树与双向链表

https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=117&&tqId=34986&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

抽象地一批...

class Solution:
    def Convert(self, root):
        if not root:
            return None
        if not root.left and not root.right:
            return root
        left = self.Convert(root.left)
        p = left
        while left and p.right:
            p = p.right
        if left:
            p.right = root
            root.left = p
        right = self.Convert(root.right)

        if right:
            right.left = root
            root.right = right

        return left if left else root

42. 合并k个已排序的链表

https://www.nowcoder.com/practice/65cfde9e5b9b4cf2b6bafa5f3ef33fa6?tpId=117&&tqId=34972&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

利用归并排序的思想,将链表合并

public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
       if(lists==null||lists.size()==0){
           return null;
       }
       return mergeKList(lists,0,lists.size()-1);
    }
    public ListNode mergeKList(ArrayList<ListNode> lists,int lo,int hi){
        if (hi<=lo) return lists.get(lo);
        int mid=lo+(hi-lo)/2;
        ListNode left = mergeKList(lists,lo,mid);
        ListNode right = mergeKList(lists,mid+1,hi);
        return merge(left,right);
    }
    public ListNode merge(ListNode left,ListNode right){
        ListNode h = new ListNode(-1);
        ListNode tmp=h;
        while(left!=null&&right!=null){
            if(left.val<right.val){
                tmp.next=left;
                left=left.next;
            }else{
                tmp.next=right;
                right=right.next;
            } tmp=tmp.next; }
        if(left!=null){
            tmp.next=left;
        }
        if(right!=null){
            tmp.next=right;
        }
        return h.next;
    }
}

43. 在两个长度相等的排序数组中找到上中位数

https://www.nowcoder.com/practice/6fbe70f3a51d44fa9395cfc49694404f?tpId=117&&tqId=35071&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

双指针遍历即可

class Solution {
public:
    int findMedianinTwoSortedAray(vector<int>& arr1, vector<int>& arr2) {
        int i = -1, j = -1, k = arr1.size() - 1;
        bool flag = true;
        while (true) {
            if (arr1[i + 1] < arr2[j + 1]) {
                ++i;
                if (!flag)  flag = true;
            }
            else {
                ++j;
                if (flag)  flag = false;
            }
            if (i == -1 && j == k || j == -1 && i == k || i + j == k - 1)  break;
        }
        if (flag) return arr1[i];
        else return arr2[j];
    }
};

44. 转圈打印矩阵

https://www.nowcoder.com/practice/fe219d47475842e68e64ba6fea42b846?tpId=117&&tqId=35276&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

模拟即可

class Solution {
    public int[] printMatrix(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return new int[0];
        }
        int m = matrix.length, n = matrix[0].length;
        int[] res = new int[m * n];
        int rowBegin = 0, rowEnd = m - 1, colBegin = 0, colEnd = n - 1;
        int index = 0;
        while (rowBegin <= rowEnd && colBegin <= colEnd) {
            for (int j = colBegin; j <= colEnd; j++) {
                res[index++] = matrix[rowBegin][j];
            }
            rowBegin++;

            for (int i = rowBegin; i <= rowEnd; i++) {
                res[index++] = matrix[i][colEnd];
            }
            colEnd--;

            if (rowBegin <= rowEnd) {
                for (int j = colEnd; j >= colBegin; j--) {
                    res[index++] = matrix[rowEnd][j];
                }
            }
            rowEnd--;

            if (colBegin <= colEnd) {
                for (int i = rowEnd; i >= rowBegin; i--) {
                    res[index++] = matrix[i][colBegin];
                }
            }
            colBegin++;
        }
        return res;
    }
}

45. 最小的K个数

https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=117&&tqId=35260&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

排序+特判

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int>& A, int k) {
        vector<int> ans;
        if (A.empty() || k>A.size()) return ans;
        sort(A.begin(), A.end());
        for (int i=0; i<k; i++) ans.push_back(A[i]);
        return ans;
    } 
};

46. 矩阵最长递增路径

https://www.nowcoder.com/practice/7a71a88cdf294ce6bdf54c899be967a2?tpId=117&&tqId=35562&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

import java.util.*;
public class Solution {
    int[][] dp;
    int[] dirs = new int[]{0,1,0,-1,0};
    int m, n;
    public int solve (int[][] matrix) {
        // write code here
        int max = 1;
        m = matrix.length;
        n = matrix[0].length;
        dp = new int[m][n];
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                max = Math.max(max,  dfs(matrix, i, j));
            }
        }
        return max;
    }
    private int dfs(int[][] matrix, int x, int y) {
        if(dp[x][y] != 0) {
            return dp[x][y];
        }
        dp[x][y] = 1;
        for(int k = 0; k < 4; k++) {
            int nx = x + dirs[k];
            int ny = y + dirs[k+1];
            if(nx>=0 && nx<m && ny>=0 && ny<n && matrix[nx][ny] < matrix[x][y]) {
                dp[x][y] = Math.max(dp[x][y], 1+dfs(matrix, nx, ny));
            }
        }
        return dp[x][y];
    }
}

47. 没有重复项数字的所有排列

https://www.nowcoder.com/practice/4bcf3081067a4d028f95acee3ddcd2b1?tpId=117&&tqId=34964&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

class Solution {
public:
    vector<vector<int>> ans;
    int vis[200];
    void dfs(vector<int>& v, vector<int>& A) {
        if (v.size()>=A.size()) {
            ans.push_back(v);
            return;
        }
        for (int i=0; i<A.size(); i++) if (!vis[i]) {
            v.push_back(A[i]), vis[i]=1;
            dfs(v,A);
            v.pop_back(), vis[i]=0;
        }
    }
    vector<vector<int> > permute(vector<int> &A) {
        vector<int> v;
        dfs(v,A);
        return ans;
    }
};

48. 有重复项数字的所有排列

https://www.nowcoder.com/practice/a43a2b986ef34843ac4fdd9159b69863?tpId=117&&tqId=34963&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:排序+去重

class Solution {
public:
    vector<vector<int>> ans;
    int vis[200];
    void dfs(vector<int>& v, vector<int>& A) {
        if (v.size()>=A.size()) {
            ans.push_back(v);
            return;
        }
        for (int i=0; i<A.size(); i++) {
            if (vis[i] || (i && A[i-1]==A[i] && vis[i-1]))
                continue;
            v.push_back(A[i]), vis[i]=1;
            dfs(v,A);
            v.pop_back(), vis[i]=0;
        }
    }
    vector<vector<int> > permuteUnique(vector<int> &A) {
        vector<int> v;
        sort(A.begin(), A.end());
        dfs(v,A);
        return ans;
    }
};

49. 加起来和为目标值的组合

https://www.nowcoder.com/practice/75e6cd5b85ab41c6a7c43359a74e869a?tpId=117&&tqId=34967&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:去重,一个数字不能选多次

class Solution {
public:
    vector<vector<int>> ans;
    void dfs(int i, vector<int>& v, vector<int>& A, int tg) {
        if (tg==0) {
            ans.push_back(v);
            return;
        }
        for (int j=i; j<A.size(); j++) {
            if (tg<A[j]) break;
            if (j>i && A[j-1]==A[j]) continue;
            v.push_back(A[j]);
            dfs(j+1,v,A,tg-A[j]);
            v.pop_back();
        }
    }
    vector<vector<int>> combinationSum2(vector<int> &A, int tg) {
        vector<int> v;
        sort(A.begin(), A.end());
        dfs(0,v,A,tg);
        return ans;
    }
};

50. 数字字符串转化成IP地址

https://www.nowcoder.com/practice/ce73540d47374dbe85b3125f57727e1e?tpId=117&&tqId=34941&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

枚举长度+剪枝

class Solution {
public:
    vector<string> ans;
    void dfs(int i, vector<string>& v, string& s) {
        if (i>s.size() || (i<s.size() && v.size()==4)) return;
        if (i==s.size() && v.size()==4) {
            string t=v[0];
            for (int j=1; j<v.size(); j++) t+="."+v[j];
            ans.push_back(t);
            return;
        }
        for (int len=1; len<=3; len++) {
            string sub=s.substr(i, len);
            if (sub[0]=='0' && sub.size()>1) continue;
            int n=atoi(sub.c_str());
            if (n>=0 && n<=255) {
                v.push_back(sub);
                dfs(i+len, v, s);
                v.pop_back();
            }
        }
    }
    vector<string> restoreIpAddresses(string s) {
        vector<string> v;
        dfs(0,v,s);
        return ans;
    }
};

51. 集合的所有子集

https://www.nowcoder.com/practice/c333d551eb6243e0b4d92e37a06fbfc9?tpId=117&&tqId=34948&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:简单回溯

class Solution {
public:
    vector<vector<int>> ans;
    void dfs(int i, vector<int>& v, vector<int> &S) {
        if (i==S.size()) return;
        v.push_back(S[i]);
        ans.push_back(v);
        dfs(i+1,v,S);
        v.pop_back();
        dfs(i+1,v,S);
    }
    vector<vector<int> > subsets(vector<int> &S) {
        vector<int> v;
        ans.push_back(v);
        dfs(0,v,S);
        return ans;
    }
};

52. 分糖果问题

https://www.nowcoder.com/practice/76039109dd0b47e994c08d8319faa352?tpId=117&&tqId=35271&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:前后递推一遍即可

class Solution {
public:
    int candy(vector<int>& A) {
        int n=A.size(); vector<int> f(n,1);
        for (int i=1; i<n; i++) if (A[i-1]<A[i]) f[i]=f[i-1]+1;
        for (int i=n-2; i>=0; i--) if (A[i]>A[i+1]) f[i]=max(f[i+1]+1, f[i]);
        return accumulate(f.begin(),f.end(),0);
    }
};

53. 缺失数字

https://www.nowcoder.com/practice/9ce534c8132b4e189fd3130519420cde?tpId=117&&tqId=35026&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:作差法

class Solution {
public:
    int solve(int* a, int n) {
        int s=n*(n+1)/2, t=accumulate(a,a+n,0);
        return s-t;
    }
};

54. 反转数字

https://www.nowcoder.com/practice/1a3de8b83d12437aa05694b90e02f47a?tpId=117&&tqId=34978&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

分类讨论,感觉说的不清楚,溢出的时候没说是取int的极值啊,全靠猜。。。

#include<bits/stdc++.h>
class Solution {
public:
    int reverse(int x) {
        string s=to_string(x), t;
        bool isNeg=false;
        if (!isdigit(s[0])) t=s.substr(1), isNeg=1;
        else t=s;
        std::reverse(t.begin(),t.end());
        long long n=stoll(t);
        if (n>INT_MAX) {
            n=INT_MAX;
        } else if (isNeg) {
            n*=-1;
            if (n<=INT_MIN) n=INT_MIN;
        }
        return (int) n;
    }
};

55. 有关阶乘的两个问题1

https://www.nowcoder.com/practice/aa03dff18376454c9d2e359163bf44b8?tpId=117&&tqId=35270&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:由于朴素解***超时,利用规律来求:
每次对n!除以5,那么它会把5除干净,由于25也存在两个5,但除以5只得到了一个5,所以还需要除以25得到另外一个无,依次类推

typedef long long ll;
class Solution {
public:
    ll thenumberof0(ll n) {
        ll c2=0, c5=0, k=5;
        while (n>=k) c5+=n/k, k*=5;
        return c5;
    }
};

55. 求平方根

https://www.nowcoder.com/practice/09fbfb16140b40499951f55113f2166c?tpId=117&&tqId=34953&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

使用:规律法,从1开始的连续奇数和一定是一个平方数

public class Solution {
    public int sqrt(int x) {
        int i = 1;
        int res = 0;
        while (x >= 0) {
            x -= i;
            res++;
            i += 2;
        }
        return res - 1;
    }
}

56. 丑数

https://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b?tpId=117&&tqId=35001&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

指针版本的动态规划

class Solution:
    def GetUglyNumber_Solution(self, index):
        if index<=0:
            return 0
        uglylist=[1]
        p2=p3=p5=0
        for i in range(index-1):
            newugly = min(uglylist[p2]*2,uglylist[p5]*5,uglylist[p3]*3)
            uglylist.append(newugly)
            if not newugly % 2:
                p2+=1
            if not newugly %3:
                p3+=1
            if not newugly %5:
                p5+=1
        return uglylist[-1]

57. 三个数的最大乘积

https://www.nowcoder.com/practice/8ae05c2913fe438b8b14f3968f64fc0b?tpId=117&&tqId=35031&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

定义五个变量,分类讨论

第一次用python,赋值竟然不能一个一个得赋

class Solution:
    def solve(self , A):
        inf = float('inf')
        max1=max2=max3=-inf
        min1=min2=inf

        for x in A:
            if x > max1:
                max3, max2, max1 = max2, max1, x
            elif x >max2:
                max3, max2 = max2, x
            elif x > max3:
                max3=x
            if x < min1:
                min2, min1 = min1, x
            elif x < min2:
                min2=x
        return max(max2*max3, min1*min2)*max1

58. 二进制中1的个数

https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=117&&tqId=35261&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

class Solution:
    def NumberOf1(self, n):
        ans=0
        n&=0xffffffff #最小负数的补码为1000 0001,而while进入条件是大于0
        while n > 0:
            x = n & 1
            if x == 1: 
                ans+=1
            n >>= 1
        return ans

59. 二叉树的最大深度

https://www.nowcoder.com/practice/8a2b2bf6c19b4f23a9bdb9b233eefa73?tpId=117&&tqId=34934&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

递归做就行了

class Solution:
    def maxDepth(self , root ):
        def dfs(root):
            if (root is None):
                return 0;
            l=dfs(root.left)
            r=dfs(root.right)
            return max(l,r)+1
        return dfs(root)

60. 平衡二叉树

https://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId=117&&tqId=34984&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

检查左右子树的最大深度差是否大于1

class Solution:
    ans=True
    def IsBalanced_Solution(self, root):
        def dfs(root):
            if root is None:
                return 0
            l=dfs(root.left)
            r=dfs(root.right)
            if abs(r-l)>1:
                self.ans=False
            return max(l,r)+1
        dfs(root)
        return self.ans

61. 判断二叉树是否对称

https://www.nowcoder.com/practice/1b0b7f371eae4204bc4a7570c84c2de1?tpId=117&&tqId=34937&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

分类讨论,一定要写两个分路的递归,不然你怎么同时检查左右子树

class Solution:
    def isSymmetric(self , root ):
        def dfs(l, r):
            if l is None and r is None:
                return True;
            if l is None or r is None:
                return False;
            return l.val==r.val and dfs(l.left, r.right) and dfs(l.right, r.left) 
        if root is None:
            return True
        return dfs(root.left, root.right)

62. 二叉树中是否存在节点和为指定值的路径

https://www.nowcoder.com/practice/508378c0823c423baa723ce448cbfd0c?tpId=117&&tqId=34930&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

简单递归

class Solution:
    ans=False
    def hasPathSum(self , root , sum ):
        def dfs(root, s):
            if self.ans or root is None:
                return
            if root.left is None and root.right is None:
                self.ans=(s==root.val)
            dfs(root.left, s-root.val)
            dfs(root.right, s-root.val)
        dfs(root, sum)
        return self.ans

63. 将升序数组转化为平衡二叉搜索树

https://www.nowcoder.com/practice/7e5b00f94b254da599a9472fe5ab283d?tpId=117&&tqId=34932&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

最好不要看样例好。数组的中间位置元素就是BST的根,然后以同样的策略递归构造左、右子树即可

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def sortedArrayToBST(self , A ):
        def dfs(l,r,A):
            if l>=r:
                return None
            m=l+r>>1
            root=TreeNode(A[m])
            root.left=dfs(l,m,A)
            root.right=dfs(m+1,r,A)
            return root
        return dfs(0,len(A),A)

64. 二叉树根节点到叶子节点的所有路径和

https://www.nowcoder.com/practice/185a87cd29eb42049132aed873273e83?tpId=117&&tqId=34926&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

注意叶子节点的判断

class Solution:
    def sumNumbers(self , root ):
        def dfs(root, x):
            if root is None:
                return 0
            x=x*10+root.val;
            if root.left is None and root.right is None:
                return x
            return dfs(root.left, x) + dfs(root.right, x)
        return dfs(root, 0)

65. 二叉树根节点到叶子节点和为指定值的路径

https://www.nowcoder.com/practice/840dd2dc4fbd4b2199cd48f2dadf930a?tpId=117&&tqId=34929&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
思路:提前判断

class Solution:
    def pathSum(self , root , sum ):
        ans=[]
        def dfs(root, s, path):
            path=path+[root.val]
            if s==root.val and not root.left and not root.right: ans.append(path)
            if root.left: dfs(root.left, s-root.val, path)
            if root.right: dfs(root.right, s-root.val, path)
        path=[]
        if not root: return path
        dfs(root,sum,path)
        return ans;

66. 岛屿数量

https://www.nowcoder.com/practice/0c9664d1554e466aa107d899418e814e?tpId=117&&tqId=35034&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

栈迭代版本的简单的搜索

class Solution:
    def solve(self , g ):
        n,m=len(g),len(g[0])
        d=[[0,1],[1,0],[-1,0],[0,-1]]
        def dfs(x,y,g):
            st=[(x,y)]
            while st:
                x,y=st.pop()
                g[x][y]='0'
                for k in range(4):
                    tx,ty=x+d[k][0],y+d[k][1]
                    if tx>=0 and tx<n and ty>=0 and ty<m and g[tx][ty]=='1':
                        st.append((tx,ty))
        ans=0
        for i in range(n):
            for j in range(m):
                if g[i][j]=='1':
                    ans+=1
                    dfs(i,j,g)
        return ans

67. 重建二叉树

https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=117&&tqId=35043&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路

  • 我们先从前序遍历得到根的值 rootVal。
  • 然后从中序遍历找出根的下标 rootID 以及根的左子树的大小 leftSize。
  • 递归地构造根的左子树和右子树。
    class Solution:
      def reConstructBinaryTree(self, pre, tin):
          n=len(pre)
          mp={}
          for i in range(0,n): mp[tin[i]]=i
          def dfs(pL,pR,iL,iR):
              if iL>iR:
                  return None
              rv=pre[pL] #根的值
              rp=mp[rv] #根在中序遍历中的为孩子
              lsz=rp-iL #左子树的大小
              root=TreeNode(rv)
              root.left=dfs(pL+1,pL+lsz,iL,rp-1)
              root.right=dfs(pL+lsz+1,pR,rp+1,iR)
              return root
          return dfs(0,n-1,0,n-1)

68. 判断一棵二叉树是否为搜索二叉树和完全二叉树

https://www.nowcoder.com/practice/f31fc6d3caf24e7f8b4deb5cd9b5fa97?tpId=117&&tqId=35077&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

中序遍历+层序遍历

class Solution {
public:
    int pre=INT_MIN;
    vector<bool> judgeIt(TreeNode* root) {
        // write code here
        bool flag1=isSearch(root);
        bool flag2=isCom(root);
        return {flag1,flag2};
    }
    bool isSearch(TreeNode*root){
        if(root){
            bool res=isSearch(root->left);
            if(!res) return false;
            if(root->val<=pre) return false;
            else pre=root->val;
            return isSearch(root->right);
        }
        return true;
    }
    bool flag=false;
    bool isCom(TreeNode* root){
        if(root==nullptr) return true;
        if(root->left==nullptr&&root->right==nullptr) return true;
        if(root->left!=nullptr&&root->right==nullptr){
            if(flag) return false;
            else flag=true;
        }
        if(root->left==nullptr&&root->right!=nullptr) return false;
        return isCom(root->left)&&isCom(root->right);
    }
};

69. 二叉树的最大路径和

https://www.nowcoder.com/practice/da785ea0f64b442488c125b441a4ba4a?tpId=117&&tqId=34927&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

dfs返回的是左右子树的最大和;
因为当前结点我们可以选择,也可以不选,所以当它为负数时,不选最好(0比负数大)

class Solution:
    ans=-float('inf')
    def maxPathSum(self , root ):
        def dfs(root):
            if not root: return 0
            ls=max(0,dfs(root.left))
            rs=max(0,dfs(root.right))
            self.ans=max(self.ans,ls+rs+root.val)
            return max(ls,rs)+root.val
        dfs(root)
        return self.ans

70. 合并两个有序的数组

https://www.nowcoder.com/practice/89865d4375634fc484f3a24b7fe65665?tpId=117&&tqId=34943&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

反向思维,哪个大就优先安排在A的末尾,不然python无法通过修改引用指向的方式来修改参数A指向的原数组

class Solution:
    def merge(self , A, n, B, m):
        i,j,k=n-1,m-1,n+m-1
        while ~i and ~j:
            if A[i]<B[j]:
                A[k]=B[j]
                k-=1
                j-=1
            else:
                A[k]=A[i]
                k-=1
                i-=1
        while ~i:
            A[k]=A[i]
            k-=1
            i-=1
        while ~j:
            A[k]=B[j]
            k-=1
            j-=1

71. 链表中倒数第k个结点

https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=117&&tqId=34991&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

class Solution:
    def FindKthToTail(self, head, k):
        if not head: return None
        slow,fast=head,head
        for i in range(k):
            if not fast: return None
            fast=fast.next
        while fast:
            slow=slow.next
            fast=fast.next
        return slow

72. 链表中环的入口节点

https://www.nowcoder.com/practice/6e630519bf86480296d0f1c868d425ad?tpId=117&&tqId=34924&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:直接存结点

class Solution:
    def detectCycle(self , head ):
        mp={}
        while head:
            if head in mp: return head
            mp[head]=True
            head=head.next
        return None

73.删除链表的倒数第n个节点

https://www.nowcoder.com/practice/f95dcdafbde44b22a6d741baf71653f6?tpId=117&&tqId=34974&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 双指针,然后修改引用指向即可

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def removeNthFromEnd(self , head , n ):
        dead,slow,fast=ListNode(-1),head,head
        dead.next=head
        for i in range(n):
            fast=fast.next
        if not fast: return head.next
        while fast and fast.next:
            slow=slow.next
            fast=fast.next
        slow.next=slow.next.next
        return dead.next

74. 容器盛水问题

https://www.nowcoder.com/practice/31c1aed01b394f0b8b7734de0324e00f?tpId=117&&tqId=35269&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

预处理左右的高度差

typedef long long ll;
const int N=1e6+5;
class Solution {
public:
    int l[N], r[N];
    ll maxWater(vector<int>& A) {
        ll n=A.size(), ans=0, lmx=0, rmx=0;
        for (int i=0; i<n; i++) {
            lmx=max(lmx,(ll) A[i]);
            rmx=max(rmx,(ll) A[n-i-1]);
            l[i]=lmx-A[i];
            r[n-i-1]=rmx-A[n-i-1];
        }
        for (int i=0; i<n; i++) ans+=min(l[i], r[i]);
        return ans;
    }
};

75. 数组中相加和为0的三元组

https://www.nowcoder.com/practice/345e2ed5f81d4017bbb8cc6055b0b711?tpId=117&&tqId=34975&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

排序+双指针即可

class Solution:
    def threeSum(self , A ):
        n,tar,ans=len(A),0,[]
        if n<3: return ans
        A=sorted(A)
        for i in range(n):
            if A[i]>0: 
                break    
            if i>0 and A[i-1]==A[i]: 
                continue
            l,r=i+1,n-1
            while l<r:
                s=A[i]+A[l]+A[r]
                if s>tar: r-=1
                elif s<tar: l+=1
                else:
                    ans.append([A[i],A[l],A[r]])
                    while l+1<r and A[l]==A[l+1]: l+=1
                    while r-1>l and A[r]==A[r-1]: r-=1
                    l+=1
                    r-=1
        return ans

76. 滑动窗口的最大值

https://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788?tpId=117&&tqId=35004&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 队列维护大小为k的窗口(元素单调递减),只有当i>=k-1时(即遍历够k个元素才输出到ans中)

class Solution:
    def maxInWindows(self, A, k):
        n,ans,q=len(A),[],[]
        if k>n or k==0: return ans
        for i in range(n):
            while q and A[i]>=A[q[-1]]: q.pop()
            q.append(i)
            while i-q[0]+1>k: q.pop(0)
            if i>=k-1: ans.append(A[q[0]])
        return ans

77. 最小覆盖子串

https://www.nowcoder.com/practice/c466d480d20c4c7c9d322d12ca7955ac?tpId=117&&tqId=34949&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

两个计数器

import collections
class Solution:
    def minWindow(self, s, t ):
        n,m=len(s),len(t)
        need=collections.Counter(t)
        mp=collections.defaultdict(int)
        l,r,ansL,ansR,mi,fd=0,0,0,0,n+5,0
        for r in range(n):
            c=s[r]
            if need[c]:
                mp[c]+=1
                if (mp[c]==need[c]): fd+=1
                while fd==len(need):
                    if mi>r-l+1:
                        mi=r-l+1
                        ansL,ansR=l,r+1
                    if need[s[l]]:
                        if mp[s[l]]==need[s[l]]:
                            fd-=1
                        mp[s[l]]-=1
                    l+=1
        return s[ansL:ansR]

78. 二分查找

https://www.nowcoder.com/practice/7bc4a1c7c371425d9faa9d1b511fe193?tpId=117&&tqId=35030&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

注意边界,以及特殊情况即可

class Solution:
    def upper_bound_(self,n,v,a ):
        if a[-1]<v: return n+1
        l,r=0,n
        while l<r:
            m=l+r>>1
            if a[m]<v:
                l=m+1
            else:
                r=m
        return l+1

79. 数字在升序数组中出现的次数

https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=117&&tqId=34996&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

简单二分

class Solution:
    def GetNumberOfK(self, A, x):
        n=len(A)
        def lower_bound():
            l,r=0,n
            while l<r:
                m = l+r>>1
                if A[m]>=x: r=m
                else: l=m+1
            return l
        def upper_bound():
            l,r=0,n
            while l<r:
                m=l+r>>1
                if A[m]>x:
                    r=m
                else:
                    l=m+1
            return l
        return upper_bound()-lower_bound()

80. 旋转数组的最小数字

https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=117&&tqId=34993&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

二分思想+处理重复元素

class Solution:
    def minNumberInRotateArray(self, A):
        l,r=0,len(A)-1
        while l<r:
            m=l+r>>1
            if A[m]>A[r]: l=m+1 #[m,r]为升序数组,且A[m]不可能成为答案
            elif A[m]<A[r]: r=m #[m,r]为降序数组,且A[m]有可能作为答案
            else: r-=1
        return A[l]

81. 矩阵查找

https://www.nowcoder.com/practice/5145394607ea4c5f8b25755718bfddba?tpId=117&&tqId=34950&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

二分思想

class Solution:
    def searchMatrix(self , g , x ):
        n,m=len(g),len(g[0])
        i,j=0,m-1
        while i<n and j>=0:
            if x>g[i][j]: i+=1
            elif x<g[i][j]: j-=1
            else: return True
        return False

82. 在转动过的有序数组中寻找目标值

https://www.nowcoder.com/practice/7cd13986c79d4d3a8d928d490db5d707?tpId=117&&tqId=34969&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

确定升序区间,在确定x在升序区间中的位置

class Solution:
    def search(self , A , x ):
        l,r=0,len(A)-1
        while l<=r:
            m=l+r>>1
            if x==A[m]: return m
            # [l,m]是升序
            if A[l]<=A[m]:
                if A[l]<=x and x<=A[m]: r=m-1
                else: l=m+1
            # [m,r]是升序
            else:
                if x>=A[m] and x<=A[r]: l=m+1
                else: r=m
        return -1

83. 完全二叉树结点数

https://www.nowcoder.com/practice/512688d2ecf54414826f52df4e4b5693?tpId=117&&tqId=35006&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

数是完全二叉树,如果左子树的树高与右子树相同,则表示左子树是满二叉树;否则,左子树的树高一定大于右子树,所以右子树是满二叉树
在这里插入图片描述
在这里插入图片描述

class Solution:
    def nodeNum(self , root ):
        def getH(root):
            h=0
            while root:
                root=root.left
                h+=1
            return h
        if not root: return 0
        lh=getH(root.left)
        rh=getH(root.right)
        if lh==rh: return (1<<lh)+self.nodeNum(root.right)
        else: return (1<<rh)+self.nodeNum(root.left)

84. 寻找峰值

https://www.nowcoder.com/practice/1af528f68adc4c20bf5d1456eddb080a?tpId=117&&tqId=35032&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

从后往前遍历到第一个升序结构即为山峰
在这里插入图片描述

class Solution:
    def solve(self , A ):
        for i in range(len(A)-1, 0, -1):
            if A[i-1]<A[i]:
                return i

85. 最长递增子序列

https://www.nowcoder.com/practice/9cf027bf54714ad889d4f30ff0ae5481?tpId=117&&tqId=35013&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

还是比较难想的一道题:

  • dp[i]表示到arr[i]为止最长的递增子序列
  • res用来存储字典序最小的最长子序列,倒序遍历dp,即可
    class Solution {
    public:
      vector<int> LIS(vector<int>& A) {
          int n=A.size();
          vector<int> dp(n);
          vector<int> minnum(n);
          int k=0;
          for(int i=0;i<n;i++){
              if(k==0||A[i]>minnum[k-1]){
                  dp[i]=k;
                  minnum[k++]=A[i];
              }
              else{
                  int l=0,r=k;
                  while(l<=r){
                      int mid=(l+r)/2;
                      if(minnum[mid]<A[i]) l=mid+1;
                      else r=mid-1;
                  }
                  minnum[l]=A[i];
                  dp[i]=l;
              }
          }
          vector<int> res(k); k--;
          for(int i=n-1;i>=0;i--){
              if(dp[i]==k)
                  res[k--]=A[i];
          }
          return res;
      }
    };

86. 在两个长度相等的排序数组中找到上中位数

https://www.nowcoder.com/practice/6fbe70f3a51d44fa9395cfc49694404f?tpId=117&rp=1&ru=%2Fta%2Fjob-code-high&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking

思路:双指针即可

import java.util.*;
public class Solution {
    public int findMedianinTwoSortedAray (int[] A, int[] B) {
        int p1=0,p2=0,mid=0;
        for(int i=0;i<A.length;i++){
            if(A[p1]<=B[p2]){
                mid=A[p1];
                p1++;
            }else{
                mid=B[p2];
                p2++;
            }
        }
        return mid;
    }
}

87. 数组中只出现一次的数字

https://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=117&&tqId=34997&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

简单计数题,位运算没想到

import collections
class Solution:
    def FindNumsAppearOnce(self, A):
        cnt=collections.defaultdict()
        for x in A: cnt[x]=cnt.get(x,0)+1
        ans=[]
        for k,v in cnt.items():
            if v==1: ans.append(k)
        return ans

相同的数字异或的结果为0,不同的数字的疑惑结果至少有一个位置的二进制位不同(这里为了方便,取最低位的1,假设在位置k);把数组分成两组:

  • 一组是第k位没有1
  • 一组是第k位有1

这样异或下来,就可以找到两个数字了

class Solution:
    def FindNumsAppearOnce(self, A):
        n=len(A)
        x,y,t=0,0,0
        for v in A: t^=v

        k=0 #t的最后一位1的位置
        for i in range(32):
            if (t>>i)&1==1:
                k=i
                break

        for v in A:
            if (v>>k)&1==1: x^=v
            else: y^=v

        return [x,y]

88. 进制转换

https://www.nowcoder.com/practice/2cc32b88fff94d7e8fd458b8c7b25ec1?tpId=117&&tqId=35037&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 注意负数,以及n大于9时的特殊情况即可

class Solution:
    def solve(self, m, n):
        def get(x):
            if 0<=x and x<10: return str(x)
            return chr(x-10+65)
        isNeg=False
        if m<0: 
            m=-m
            isNeg=True
        ans=''
        while m>0:
            ans=get(m%n)+ans
            m/=n
        return '-'+ans if isNeg else ans

89. 数组中的最长连续子序列

https://www.nowcoder.com/practice/eac1c953170243338f941959146ac4bf?tpId=117&&tqId=35017&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:排序+统计连续的数字的个数

class Solution {
public:
    int MLS(vector<int>& A) {
        sort(A.begin(), A.end());
        int n=A.size(), ans=1, cur=1;
        for (int i=1; i<n; i++) if (A[i-1]!=A[i]) {
            if (A[i-1]+1==A[i]) {
                cur++;
                ans=max(ans, cur);
            } else {
                cur=1; //遇到不连续的就赋初值
            }
        }
        return ans;
    }
};

90. 求二叉树的层序遍历

https://www.nowcoder.com/practice/04a5560e43e24e9db4595865dc9c63a3?tpId=117&&tqId=34936&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 记录深度的递归求解

class Solution:
    def levelOrder(self , root ):
        ans=[]
        def dfs(root, d):
            if not root: return
            if len(ans)==d: ans.append([root.val])
            else: ans[d].append(root.val)
            dfs(root.left, d+1)
            dfs(root.right, d+1)
        dfs(root,0)
        return ans

91. 把二叉树打印成多行

https://www.nowcoder.com/practice/445c44d982d04483b04a54f298796288?tpId=117&&tqId=35002&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 层序遍历+py的细节处理即可

class Solution:
    def Print(self, root):
        if not root: return []
        ans,q=[],[]
        d=0
        q.append(root)
        while q:
            sz=len(q)
            for i in range(sz):
                t=q.pop(0)
                if len(ans)==d: ans.appe***al])
                else: ans[d].appe***al)
                if t.left: q.append(t.left)
                if t.right: q.append(t.right)
            d+=1
        return ans

92. 二叉树的之字形层序遍历

https://www.nowcoder.com/practice/47e1687126fa461e8a3aff8632aa5559?tpId=117&&tqId=34935&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 层序遍历+奇数层逆序

class Solution:
    def zigzagLevelOrder(self , root ):
        if not root: return []
        ans,q=[],[]
        d=0
        q.append(root)
        while q:
            sz=len(q)
            for i in range(sz):
                t=q.pop(0)
                if len(ans)==d: ans.appe***al])
                else: ans[d].appe***al)
                if t.left: q.append(t.left)
                if t.right: q.append(t.right)
            if d&1: ans[d].reverse()
            d+=1
        return ans

93. 用两个栈实现队列

https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=117&&tqId=34998&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:
题意清晰很友好,直接两个栈实现队列(用一个缓存栈临时存储数据)

class Solution:
    st,cache=[],[]
    def push(self, x):
        self.st.append(x)
    def pop(self):
        while self.st:
            self.cache.append(self.st[-1])
            self.st.pop(-1)
        ans=self.cache.pop(-1)

        while self.cache:
            self.st.append(self.cache[-1])
            self.cache.pop(-1)
        return ans

94. 设计getMin功能的栈

https://www.nowcoder.com/practice/c623426af02d4c189f92f2a99647bd34?tpId=117&&tqId=35012&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 双栈伺候,因为要存储过程中的全部最小值,所以需要另一个栈存储越新鲜的最小值

class Solution:
    def getMinStack(self , ops ):
        st,mst,ans=[],[],[]
        for op in ops:
            if op[0]==1:
                st.append(op[1])
                if not mst or mst[-1]>op[1]:
                    mst.append(op[1])
            elif op[0]==2:
                top=st.pop(-1)
                if mst and mst[-1]==top:
                    mst.pop(-1)
            else:
                ans.append(mst[-1])
        return ans

95. 实现二叉树先序,中序和后序遍历

https://www.nowcoder.com/practice/a9fec6c46a684ad5a3abd4e365a9d362?tpId=117&&tqId=35075&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 啊这,换个位置?说什么呢?正经思路是:
先序:根左右
中序:左根右
后序:左右根

递归版本没啥难度

class Solution:
    def threeOrders(self , root ):
        pre,inn,post=[],[],[]
        def dfs(root):
            if not root: return
            pre.append(root.val)
            dfs(root.left)
            inn.append(root.val)
            dfs(root.right)
            post.append(root.val)

        dfs(root)
        ans=[pre,inn,post]
        return ans

96. 表达式求值

https://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4?tpId=117&&tqId=35561&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:

  1. 用栈保存各部分计算的和
  2. 遇到数字时继续遍历求这个完整的数字的值
  3. 遇到(时递归求括号里面的值
    class Solution {
    public:
     int solve(string s) {
         int k=0;
         return helper(s,k);
     }
     int helper(string s,int &index){
         stack<int> s1;
         char sign='+';
         int res=0;
         for( index;index<s.size();index++){
             if(isdigit(s[index])){
                 res=res*10+(s[index]-'0');
             }
             if(s[index]=='+'||s[index]=='-'||s[index]=='*'||(index==s.size()-1)){
                if(sign=='+'){
                     s1.push(res);
                }else if(sign=='-')
                 {
                     s1.push(-res);
                 }else{
                 int k1=s1.top();
                 s1.pop();
                 s1.push(k1*res);
                }
                 res=0;
                 sign=s[index];
             }
             if(s[index]=='('){
                 index++;
                 res=helper(s,index);
             }else if(s[index]==')'){
                 break;
             }
         }
         if(res!=0){
             if(sign=='+'){
                     s1.push(res);
                }else if(sign=='-')
                 {
                     s1.push(-res);
                 }else{
                 int k1=s1.top();
                 s1.pop();
                 s1.push(k1*res);
             }
         }
         int sum=0;
         while(!s1.empty()){
             sum+=s1.top();
             s1.pop();
         }
         return sum;
     }
    };

97. 栈和排序

https://www.nowcoder.com/practice/95cb356556cf430f912e7bdf1bc2ec8f?tpId=117&&tqId=35040&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 贪心+栈
顺序遍历数组时,怎样才能知道后面的元素是否有大于自己的呢,答案是数组预处理

因为FILO的特性,我们要先把栈中的大元素先弄进ans

const int N=1e6+5;
class Solution {
public:
    int mx[N];
    vector<int> solve(int* A, int n) {
        vector<int> ans;
        stack<int> st;
        memset(mx, -1, sizeof mx);
        for (int i=n-1; ~i; i--) mx[i]=max(mx[i+1], A[i]);
        for (int i=0; i<n; i++) {
            st.push(A[i]);
            if (mx[i]==A[i]) {
                ans.push_back(st.top()), st.pop();
                while (i+1<n && !st.empty() && st.top()>mx[i+1])
                    ans.push_back(st.top()), st.pop();
            }
        }
        while (!st.empty()) ans.push_back(st.top()), st.pop();
        return ans;
    }
};

98. 序列化二叉树

https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84?tpId=117&&tqId=35264&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 只要是能遍历一棵树的方法都行,这里采用层序遍历

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
}
function Serialize(pRoot)
{
    if (!pRoot) return "";
    let res = [];
    let tree = [pRoot];
    while (tree.length) {
        let len = tree.length;
        for (let i = 0; i < len; i++) {
            let node = tree.shift();
            if (!node) {
                res.push("#");
                continue;
            }
            res.push(node.val);
            tree.push(node.left, node.right);
        }
    }
    return res.join(" ");
}
function Deserialize(s)
{
    if (!s) return null;
    let arr = s.split(/\s/g);
    let root = new TreeNode(arr[0]);
    let tree = [root];
    let i = 1;
    while (tree.length){
        let node = tree.shift();
        if (!node) continue;
        node.left = arr[i] !== "#" ? new TreeNode(arr[i]) : null;
        node.right = arr[i + 1] !== "#" ? new TreeNode(arr[i + 1]) : null;
        i += 2;
        tree.push(node.left, node.right);
    }
    return root;
}
module.exports = {
    Serialize : Serialize,
    Deserialize : Deserialize
};

99. 合并二叉树

https://www.nowcoder.com/practice/7298353c24cc42e3bd5f0e0bd3d1d759?tpId=117&&tqId=35042&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 始终以一棵树为基准进行合并,且返回这个节点

class Solution:
    def mergeTrees(self , t1 , t2 ):
        def dfs(p, q):
            if not ***ot q: return p if p else q
            p.val+=q.val
            p.left=dfs(p.left, q.left)
            p.right=dfs(p.right, q.right)
            return p
        return dfs(t1,t2)

100. 二叉树的镜像

https://www.nowcoder.com/practice/564f4c26aa584921bc75623e48ca3011?tpId=117&&tqId=34994&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 不断交换即可,不难

class Solution:
    def Mirror(self, root):
        def dfs(root):
            if not root: return
            root.left,root.right=root.right,root.left
            dfs(root.left)
            dfs(root.right)
        dfs(root)
        return root

101. 判断t1树中是否有与t2树拓扑结构完全相同的子树

https://www.nowcoder.com/practice/4eaccec5ee8f4fe8a4309463b807a542?tpId=117&&tqId=35022&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 双指针判断子序列的思想

public class Solution {
    public boolean isContains (TreeNode p, TreeNode q) {
        if (q==null) return true;
        if (p==null) return false;
        if (p.val==q.val) return isContains(p.left, q.left) && isContains(p.right, q.right);
        return isContains(p.left, q) || isContains(p.right, q);
    }
}

102. 树的直径

https://www.nowcoder.com/practice/a77b4f3d84bf4a7891519ffee9376df3?tpId=117&&tqId=35024&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 记录最大与次大即可

class Solution {
public:
    int ans = INT_MIN;
    int solve(int n, vector<Interval>& Tree_edge, vector<int>& Edge_value) {
        vector<vector<pair<int,int>> > g(n);
        for(int i = 0; i < Tree_edge.size(); i++){
            auto e = Tree_edge[i];
            g[e.start].push_back(make_pair(e.end, Edge_value[i]));
            g[e.end].push_back(make_pair(e.start, Edge_value[i]));
        }
        int pre = -1, cur = 0;
        dfs(g, pre, cur); 
        return ans;
    }
    int dfs(vector<vector<pair<int,int>> >& g, int pre, int cur){
        int d1 = 0, d2 = 0;//d1保最大值,d2保存次大值
        for(int i = 0; i < g[cur].size(); i++){
            int node = g[cur][i].first;//当前节点相连接的下一个节点
            if(node != pre){//判断当前的节点不是和它相连接的上一个节点
                int d = dfs(g, cur, node) + g[cur][i].second;
                if(d > d1){
                    d2 = d1;
                    d1 = d;
                }else if(d > d2){
                    d2 = d;
                }
            }
        }
        ans = max(ans, d1 + d2);//保存当前遍历过的元素的最大路径
        return d1;
    }
};

103. 二叉搜索树的第k个结点

https://www.nowcoder.com/practice/ef068f602dde4d28aab2b210e859150a?tpId=117&&tqId=35003&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 非递归模拟计算机压栈退栈

class Solution:
    def KthNode(self, root, k):
        ans,p,st=None,root,[]
        while st or p:
            if p:
                st.append(p)
                p=p.left
            else:
                p=st.pop()
                if k-1==0: return p
                k-=1
                p=p.right
        return None

104. 输出二叉树的右视图

https://www.nowcoder.com/practice/c9480213597e45f4807880c763ddd5f0?tpId=117&&tqId=35560&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 构造二叉树,然后优先遍历右子树,在遍历左子树

import collections

class Solution:
    def solve(self, pre, inn):
        def dfs(pL, pR, iL, iR, pre, inn):
            if pL>pR: return None
            rp=mp[pre[pL]]
            lsz=rp-iL
            root=TreeNode(pre[pL])
            root.left=dfs(pL+1,pL+lsz,iL,rp-1,pre,inn)
            root.right=dfs(pL+lsz+1,pR,rp+1,iR,pre,inn)
            return root

        n,mp=len(pre),collections.defaultdict(int)
        for i in range(n): mp[inn[i]]=i
        root=dfs(0,n-1,0,n-1,pre,inn)

        def get(root,ans,d):
            if not root: return
            if d==len(ans): ans.append(root.val)
            get(root.right,ans,d+1)
            get(root.left,ans,d+1)
        ans=[]
        get(root,ans,0)
        return ans

105. 在二叉树中找到两个节点的最近公共祖先

https://www.nowcoder.com/practice/e0cc33a83afe4530bcec46eba3325116?tpId=117&&tqId=35027&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 遍历q及其父节点,如果list的父节点中含有,则返回,即为最近的共同祖先

import java.util.*;
public class Solution {
    HashMap<Integer,Integer> mp = new HashMap<>();
    public int lowestCommonAncestor (TreeNode root, int p, int q) {
        if(root.val==p||root.val==q) return root.val;
        ArrayList<Integer> list = new ArrayList<>();
        dfs(root);
        list.add(p);
        while(mp.get(p)!=null){
            list.add(mp.get(p));
            p = mp.get(p);
        }
        if(list.contains(q)) return q;
        //遍历q的祖先,找出最近的公共祖先
        while(mp.get(q)!=null){
            q = mp.get(q);
            if(list.contains(q)) return q;
        }
        return -1;
    }
    void dfs(TreeNode root){
        if(root.left!=null){
            mp.put(root.left.val,root.val);
            dfs(root.left);
        }
        if(root.right!=null){
            mp.put(root.right.val,root.val);
            dfs(root.right);
        }
    }
}

106. 找到搜索二叉树中两个错误的节点

https://www.nowcoder.com/practice/4582efa5ffe949cc80c136eeb78795d6?tpId=117&&tqId=35076&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 中序遍历+用pre记录当前结点的前一个结点,两个结点交换了会发生什么?第一个降序结构的第一个结点是err[0],最后一个降序结构的第一个结点是err[1]

class Solution {
public:
    vector<int> findError(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* pre=NULL;
        int u=-1,v;
        while (!st.empty() || root!=NULL) {
            if (root!=NULL) {
                st.push(root);
                root=root->left;
            } else {
                root=st.top(); st.pop();
                if (pre!=NULL && pre->val>root->val) {
                    if (u==-1) u=pre->val;
                    v=root->val;
                }
                pre=root;
                root=root->right;
            }
        }
        return {v,u};
    }
};

107. 两数之和

https://www.nowcoder.com/practice/20ef0972485e41019e39543e8e895b7f?tpId=117&&tqId=34983&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 直接map记录数字的位置

import collections
class Solution:
    def twoSum(self , A , tar ):
        n=len(A)
        mp=collections.defaultdict(int)
        for i in range(n):
            if mp.get(tar-A[i]): return [mp[tar-A[i]], i+1]
            mp[A[i]]=i+1
        return []

108. 未排序数组中累加和为给定值的最长子数组长度

https://www.nowcoder.com/practice/704c8388a82e42e58b7f5751ec943a11?tpId=117&&tqId=35266&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: mp记录前缀和的位置,前缀和0的位置默认为0(特殊处理)

import collections
class Solution:
    def maxlenEqualK(self , A , k ):
        n,s,ans=len(A),0,0
        mp={0:-1}
        for i in range(n):
            s+=A[i]
            if s-k in mp:
                ans=max(ans, i-mp[s-k])
            if s not in mp:
                mp[s]=i
        return ans

109. 出现次数的TopK问题

https://www.nowcoder.com/practice/fd711bdfa0e840b381d7e1b82183b3ee?tpId=117&&tqId=35559&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 先对数组排序,在用map统计频次,over

import collections
class Solution:
    def topKstrings(self , A , k ):
        A.sort()
        cnt=collections.defaultdict(int)
        for s in A:
            cnt[s]+=1
        list=sorted(cnt.items(), key=lambda x:x[1], reverse=True)
        return [[str(list[i][0]), str(list[i][1])] for i in range(k)]

110. 找到字符串的最长无重复字符子串

https://www.nowcoder.com/practice/b56799ebfd684fb394bd315e89324fb4?tpId=117&&tqId=35074&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 字典记录每个数字出现的位置,双指针做即可

class Solution:
    def maxLength(self , A ):
        my_dict = {}
        left, right = 0, 0
        n,ans = len(A), float('-inf')
        while right<=n-1:
            if not A[right] in my_dict:
                my_dict[A[right]] = right
                right += 1
            else:
                ans = max(ans, right - left)
                for i in range(left, my_dict[A[right]]):
                    my_dict.pop(A[i])
                left = my_dict[A[right]]+1
                my_dict[A[right]] = right
                right += 1
        ans = max(ans, right - left)
        return ans

111. 数独

https://www.nowcoder.com/practice/5e6c424b82224b85b64f28fd85761280?tpId=117&&tqId=34968&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 简单回溯,能否填数字即可

class Solution:
    def solveSudoku(self , g ):
        num_set = set([str(i) for i in range(1,10)])
        v_set = [set() for i in range(9)]
        h_set = [set() for i in range(9)]
        s_set = [set() for i in range(9)]

        def get_part(x,y):
            return x//3*3+y//3

        def set_num(x,y,num):
            v_set[x].add(num)
            h_set[y].add(num)
            s_set[x//3*3+y//3].add(num)
            g[x][y] = num

        def remove_num(x,y,num):
            v_set[x].remove(num)
            h_set[y].remove(num)
            s_set[x//3*3+y//3].remove(num)
            g[x][y] = "."

        for i in range(9):
            for j in range(9):
                if g[i][j]!=".":
                    v_set[i].add(g[i][j])
                    h_set[j].add(g[i][j])
                    s_set[i//3*3+j//3].add(g[i][j])

        def is_valid(x,y,num):
            if num not in v_set[x] and num not in h_set[y] and num not in s_set[x//3*3+y//3]:
                return True
            return False

        def backtrack(x,y):
            if x>8:
                return True
            if y>8:
                return backtrack(x+1,0)
            if g[x][y]!=".":
                return backtrack(x,y+1)
            for i in range(1,10):
                str_i = str(i)
                if is_valid(x,y,str_i):
                    set_num(x,y,str_i)
                    if backtrack(x,y+1):
                        return True
                    remove_num(x,y,str_i)
            return False

        backtrack(0,0)
        return g

112. 随时找到数据流的中位数(*)

https://www.nowcoder.com/practice/8c5e99acb1fa4bc3a342cd321100c0cd?tpId=117&&tqId=35272&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
思路:

113. 跳台阶

https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=117&&tqId=34990&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 简单递推

class Solution:
    def jumpFloor(self, n):
        f=[0]*(int(1e5+5))
        f[0]=f[1]=1
        for i in range(2,n+1):
            f[i]=f[i-1]+f[i-2]
        return f[n]

114. 拼接所有的字符串产生字典序最小的字符串

https://www.nowcoder.com/practice/f1f6a1a1b6f6409b944f869dc8fd3381?tpId=117&&tqId=35274&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: a<b,则有:a+b<b+a

class Solution {
public:
    string minString(vector<string>& A) {
        string ans;
        sort(A.begin(), A.end(), [&](const string& a, const string& b) {
            return a+b<b+a;
        });
        for (string& s : A) ans+=s;
        return ans;
    }
};

115. 丢棋子问题(*)

https://www.nowcoder.com/practice/d1418aaa147a4cb394c3c3efc4302266?tpId=117&&tqId=35279&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:

116. 二叉搜索树与双向链表

https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=117&&tqId=34986&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 记录当前结点的前驱结点

class Solution:
    forword,head=None,None
    def Convert(self , root ):
        def dfs(root):
            if not root: return
            dfs(root.left)    
            if not self.head:
                self.forword=root
                self.head=root
            else:
                self.forword.right=root
                root.left=self.forword
                self.forword=root
            dfs(root.right)
        dfs(root)
        return self.head

117. 顺时针旋转矩阵

https://www.nowcoder.com/practice/2e95333fbdd4451395066957e24909cc?tpId=117&&tqId=35045&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
在这里插入图片描述
思路: 找规律

class Rotate:
    def rotateMatrix(self, g, n):
        ans=[[0]*n for i in range(n)]
        for i in range(n):
            for j in range(n):
                ans[j][n-i-1]=g[i][j]
        return ans

118. 螺旋矩阵

https://www.nowcoder.com/practice/7edf70f2d29c4b599693dc3aaeea1d31?tpId=117&&tqId=34959&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 不断换方向即可,简单模拟

class Solution:
    def spiralOrder(self , matrix ):
        res = [];
        if (len(matrix) == 0 or len(matrix[0]) == 0):
            return res;
        rowBegin = 0;
        rowEnd = len(matrix) - 1;
        colBegin = 0;
        colEnd = len(matrix[0]) - 1;

        while (rowBegin <= rowEnd and colBegin <= colEnd) :
            # Traverse Right
            for j in range(colBegin, colEnd+1, 1):
                res.append(matrix[rowBegin][j]);
            rowBegin += 1
            # Traverse Down
            for j in range(rowBegin, rowEnd+1, 1):
                res.append(matrix[j][colEnd]);
            colEnd -= 1
            if (rowBegin > rowEnd or colBegin > colEnd) :
                break;
            # Traverse Left
            for j in range(colEnd, colBegin-1, -1):
                res.append(matrix[rowEnd][j]);
            rowEnd -= 1
            # Traverse Up
            for j in range(rowEnd, rowBegin-1, -1):
                res.append(matrix[j][colBegin]);
            colBegin += 1
        return res;

119. 合并区间

https://www.nowcoder.com/practice/69f4e5b7ad284a478777cb2a17fb5e6a?tpId=117&&tqId=34958&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 先按start升序排序,然后如果有重叠,则判断是两个区间合起来后包含还是扩展,没有重叠直接加到ans即可

class Solution:
    def merge(self , A ):
        n,ans=len(A),[]
        A.sort(key=lambda x : x.start)
        for e in A:
            if ans and ans[-1].end>=e.start:
                ans[-1].end=max(ans[-1].end, e.end)
            else:
                ans.append(e)
        return ans

120. N皇后问题

https://www.nowcoder.com/practice/c76408782512486d91eea181107293b6?tpId=117&&tqId=35072&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
思路: 位运算解法

import java.util.*;
public class Solution {
    private int count = 0;
    public int Nqueen(int n) {
        if (n < 1) return 0;
        dfs(0,0,0,0,n);
        return count;
    }
    private void dfs(int row, int col, int pie, int na,int n) {
        if (row >= n) {
            count++;
            return;
        }
        int bit = (~(col | pie | na)) 
            & ((1<<n) - 1);  // 去掉所有高位
        while (bit > 0) {
            int p = bit & -bit;
            dfs(row + 1,col | p,(pie | p ) << 1,(na | p) >> 1,n);
            bit &= (bit - 1); 
        }
    }
}

121. 数组中未出现的最小正整数

https://www.nowcoder.com/practice/8cc4f31432724b1f88201f7b721aa391?tpId=117&&tqId=35069&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: ans记录最小正数,set记录整数的出现,只要是连续的,就记录下来

import collections
class Solution:
    def minNumberdisappered(self, A):
        ans=1
        st=collections.defaultdict(bool)
        for x in A:
            st[x]=1
            while (st.get(ans,False)): ans+=1
        return ans

122. 数组中未出现的最小正整数

https://www.nowcoder.com/practice/8cc4f31432724b1f88201f7b721aa391?tpId=117&&tqId=35069&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 作差法(前提是要保证A加上这个缺失的数字是连续数组)

class Solution:
    def minNumberdisappered(self, A):
        s1=s2=0
        mi,mx=float('inf'),-float('inf')
        for x in A:
            mi=min(mi,x)
            mx=max(mx,x)
            s1+=x
        for i in range(mi,mx+1):
            s2+=i
        ans=mx+1 if s1==s2 else s2-s1 #没有/有缺失的正数
        return max(1,ans)

123. 回文数字

https://www.nowcoder.com/practice/35b8166c135448c5a5ba2cff8d430c32?tpId=117&&tqId=34977&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 从低位开始取即可

import sys
class Solution:
    def isPalindrome(self, x: int) -> bool:
        t,v,inf=x,0,sys.maxsize
        if x<0: return False
        while x:
            dig=x%10
            v=v*10+dig
            x=x//10
        if v>inf: v=inf
        return t==v

124. 扑克牌顺子

https://www.nowcoder.com/practice/762836f4d43d43ca9deb273b3de8e1f4?tpId=117&&tqId=34985&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 从数组中的最小值开始,检查是否可以用有限的0代替缺失的数字,如果能,返回true;当然,一种特殊情况

class Solution:
    def IsContinuous(self, A):
        if not A: return False
        n,cnt,mp=len(A),[0],[False]*50
        mi,mx=float('inf'),-float('inf')
        for x in A:
            if x==0: 
                cnt[x]+=1
            else:
                mp[x]=True
                mi=min(mi,x)
                mx=max(mx,x)
        l=0
        for i in range(mi,mx+1):
            if mp[i]: 
                l+=1
            else:
                if cnt[0]>0: 
                    cnt[0]-=1
                    l+=1
                else:
                    return False
        if l<n:
            while cnt[0]>0:
                l+=1
                cnt[0]-=1
        return l==n

125. 斐波那契数列

https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=117&&tqId=34987&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路: 简单递推

class Solution:
    def Fibonacci(self, n):
        if not n: return 0
        a,b,c=0,1,1
        for i in range(n-2):
            a=b
            b=c
            c=a+b
        return c

126. 单链表的排序

https://www.nowcoder.com/practice/f23604257af94d939848729b1a5cda08?tpId=117&&tqId=35275&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:先存储后到列表中,链接成链表

class Solution:
    def sortInList(self , head ):
        A=[]
        ans,t=ListNode(-1),head
        while t:
            A.appe***al)
            t=t.next
        A.sort()
        cur=ListNode(A[0])
        ans.next=cur
        for i in range(1,len(A)):
            nxt=ListNode(A[i])
            cur.next=nxt
            cur=nxt
        return ans.next

126. 括号生成

https://www.nowcoder.com/practice/c9addb265cdf4cdd92c092c655d164ca?tpId=117&&tqId=35485&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:先放左括号,再放右括号

class Solution:
    def generateParenthesis(self , n ):
        def dfs(l,r,s,A):
            if l==0 and r==0:
                A.append(s)
                return  
            if l>0: dfs(l-1,r,s+'(',A)
            if l<r: dfs(l,r-1,s+')',A)
        A=[]
        dfs(n,n,'',A)
        return A

127. 调整数组顺序使奇数位于偶数前面

https://www.nowcoder.com/practice/beb5aa231adc45b2a5dcc5b62c93f593?tpId=117&&tqId=34999&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:开两个数组,分别存储偶数和奇数

class Solution:
    def reOrderArray(self , A ):
        oi,ei,loi,lei,n=-1,-1,-1,-1,len(A)
        B,C=[],[]
        for i in range(n):
            if A[i]&1: B.append(A[i])
            else: C.append(A[i])
        B+=C
        return B

128. 字符串变形

https://www.nowcoder.com/practice/c3120c1c1bc44ad986259c0cf0f0b80e?tpId=117&&tqId=35011&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:翻转单词即可

class Transform:
    def trans(self, s, n):
        ans=''
        for c in s:
            if c==' ': ans+=c
            elif c.isupper(): ans+=c.lower()
            else: ans+=c.upper()
        A=ans.split(' ')
        return ' '.join(A[::-1])

129. 将字符串转化为整数

https://www.nowcoder.com/practice/44d8c152c38f43a1b10e168018dcc13f?tpId=117&&tqId=35486&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:注意细节即可

class Solution:
    def atoi(self , str ):
        min_int = -(1<<31)
        max_int = (1<<31)-1
        str = str.strip()
        if str == '': return 0
        sign = 1
        if str[0] == '-':
            sign = -1
            str = str[1: len(str)]
        elif str[0] == '+':
            str = str[1: len(str)]
        length, end = len(str), len(str)
        for i in range(length):
            if str[i]>='0' and str[i]<='9': continue
            else:
                end = i
                break
        str = str[0: end]
        if str == '': return 0
        else:
            ans = sign*int(str)
            if ans < min_int:
                ans = min_int
            if ans > max_int:
                ans = max_int
            return ans

130. 比较版本号

https://www.nowcoder.com/practice/2b317e02f14247a49ffdbdba315459e7?tpId=117&&tqId=35029&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:遇到数字则累加,两个指针遇到.时则比较数字大小

class Solution:
    def compare(self , s: str, t: str):
        i,j,n,m=0,0,len(s),len(t)
        a=b=0
        while i<n and j<m:
            if s[i].isdigit(): 
                a=a*10+int(s[i])
                i+=1
            if t[j].isdigit(): 
                b=b*10+int(t[j])
                j+=1
            if i<n and j<m and s[i]=='.' and t[j]=='.':
                if a<b: return -1
                elif a>b: return 1
                a=b=0
                i,j=i+1,j+1
        if n-i==m-j: return 0
        return -1 if n-i<m-j else 1

131. 设计LRU缓存结构

https://www.nowcoder.com/practice/e3769a5f49894d49b871c09cadd13a61?tpId=117&&tqId=35015&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:模拟即可,代码有点多

class Solution {
public:
    vector<int>ans;
    vector<int> LRU(vector<vector<int> >& operators, int k) {
        vector<int> r;
        vector<int> key;
        for(int i = 0; i < operators.size(); i++){
            if(operators[i][0] == 1){
                set(operators[i][1], operators[i][2], r, key, k);
            }
            if(operators[i][0] == 2){
                get(operators[i][1], r, key);
            }
        }
        return ans;
    }
    void set(int a, int b, vector<int> &r, vector<int> &key, int k){
        if(r.size() < k){
            key.push_back(a);
            r.push_back(b);
        }
        else{
            key.erase(key.begin());
            r.erase(r.begin());
            key.push_back(a);
            r.push_back(b);
        }
    }
    void get(int a, vector<int> &r, vector<int> &key){
        int t = -1;
        for(int i = 0; i < key.size(); i++){
            if(a == key[i]){
                t = i;
                break;    
            }
        }
        if(t == -1){
            ans.push_back(-1);
        }
        else{
            int t1, t2;
            t1 = key[t];
            t2 = r[t];
            key.erase(key.begin() + t);
            r.erase(r.begin() + t);
            key.push_back(t1);
            r.push_back(t2);
            ans.push_back(t2);
        }
    }
};

132. 判断回文

https://www.nowcoder.com/practice/e297fdd8e9f543059b0b5f05f3a7f3b2?tpId=117&&tqId=36040&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:双指针遍历判断即可

class Solution:
    def judge(self , s ):
        l,r=0,len(s)-1
        while l<r:
            if s[l]!=s[r]: return False
            l,r=l+1,r-1
        return True

132. 旋转字符串

https://www.nowcoder.com/practice/80b6bb8797644c83bc50ac761b72981c?tpId=117&&tqId=35039&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:枚举每一种情况即可

class Solution:
    def solve(self , A , B ):
        n=len(A)
        for i in range(1,n):
            fir,sec=A[0:i],A[i:]
            t=sec+fir
            if t==B: return True
        return False

133. 旋转数组

https://www.nowcoder.com/practice/e19927a8fd5d477794dac67096862042?tpId=117&&tqId=35035&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:模拟即可

class Solution {
public:
    vector<int> solve(int n, int m, vector<int>& a) {
        vector<int> d;
        int finished = 0, count = a.size();
        for (int i=0; i < count; ++i) {
            if (finished >= count)
                break;
            int begin = i;
            int cur = i;
            int tmp = a[cur];
            int prev = prev_index(cur, m, n);
            while (begin != prev) {
                d.push_back(cur);
                d.push_back(prev);
                d.push_back(0);
                finished++;
                a[cur] = a[prev];
                cur = prev;
                prev = get(cur, m, n);
            }
            finished++;
            d.push_back(cur);
            d.push_back(tmp);
            d.push_back(0);
            a[cur] = tmp;
        }
        for (auto& i : a) d.push_back(i);
        return a;
    }
    int get(int i, int len, int count) {
        i -= len;
        while (i < 0) i += count;
        return i;
    }
};

134. 验证IP地址

https://www.nowcoder.com/practice/55fb3c68d08d46119f76ae2df7566880?tpId=117&&tqId=35038&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:模拟即可

class Solution:
    def solve(self , s ):
        def isIPV4(A):
            for s in A:
                if s.startswith("0") or len(s)>3 or int(s)>255: return False
            return True

        def isIPV6(A):
            for s in A:
                if len(s)>4: return False
            return True
        A=s.split(".")
        B=s.split(":")
        if not isIPV4(A) and not isIPV6(B): return "Neither"
        return "IPv4" if isIPV4(A) else "IPv6"

135. 数组中的逆序对

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=117&&tqId=35259&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:双指针模拟即可

class Solution:
    ans,mod=0,int(1e9+7)
    def InversePairs(self, A):
        def merge_sort(l,r,A):
            if l>=r: return
            m=l+r>>1
            merge_sort(l,m,A)
            merge_sort(m+1,r,A)
            i,j,B=l,m+1,[]
            while i<=m and j<=r:
                if A[i]<A[j]:
                    B.append(A[i])
                    i+=1
                else:
                    B.append(A[j])
                    self.ans+=m-i+1
                    j+=1
            while i<=m: 
                B.append(A[i])
                i+=1
            while j<=r: 
                B.append(A[j])
                j+=1
            i,j=l,0
            while i<=r:
                A[i]=B[j]
                i,j=i+1,j+1
        n=len(A)
        merge_sort(0,n-1,A)
        return self.ans%self.mod

136. 字典树的实现

https://www.nowcoder.com/practice/a55a584bc0ca4a83a272680174be113b?tpId=117&&tqId=35487&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:直接用列表实现

class Solution:
    def trieU(self , operators ):
        strs, result = [],[]
        for i in range(len(operators)):
            case = int(operators[i][0])
            string = operators[i][1]
            if case == 1:
                self.add(strs, string)
            elif case == 2:
                self.delete(strs, string)
            elif case == 3:
                self.search(strs, string, result)
            elif case == 4:
                self.cnt(strs, string, result)
        return result

    def add(self, strs, string):
        strs.append(string)

    def delete(self, strs, string):
        idx = strs.index(string)
        del strs[idx]

    def search(self, strs, string, result):
        if string in strs:
            result.append('YES')
        else:
            result.append('NO')

    def cnt(self, strs, string, result):
        count = 0
        if len(strs) > 0:
            for s in strs:
                if s.startswith(string):
                    count += 1
        result.append(str(count))

137. 孩子们的游戏(圆圈中最后剩下的数)

https://www.nowcoder.com/practice/f78a359491e64a50bce2d89cff857eb6?tpId=117&&tqId=36038&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:m模拟即可

class Solution:
    def LastRemaining_Solution(self, n, m):
        i,A=0,list(range(n))
        while len(A)>1:
            i=(i+m-1)%len(A)
            A.pop(i)
        return -1 if len(A)==0 else A[0]

138. 环形链表的约瑟夫问题

https://www.nowcoder.com/practice/41c399fdb6004b31a6cbb047c641ed8a?tpId=117&&tqId=35273&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:模拟即可

class Solution {
public:
    int dfs(int n, int m) {
        if (n==1) return 0;
        int j=dfs(n-1,m);
        return (j+m)%n;
    }
    int ysf(int n, int m) {
        return dfs(n,m)+1;
    }
};

139. 矩阵最长递增路径

https://www.nowcoder.com/practice/7a71a88cdf294ce6bdf54c899be967a2?tpId=117&&tqId=35562&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:f用局部变量可以过,用全局变量不可以过

const int N=2005, dir[4][2] = { {1,0},{0,-1},{0,1},{-1,0} };
class Solution {
public:
    int n,m,ans=1;
    int dfs(int x, int y, vector<vector<int>>& f, vector<vector<int> >& g) {
        if (f[x][y]) return f[x][y];
        int mx=1;
        for (auto& d : dir) {
            int tx=x+d[0], ty=y+d[1];
            if (tx>=0 && tx<n && ty>=0 && ty<m && g[tx][ty]>g[x][y])
                mx=max(mx,dfs(tx,ty,f,g)+1);
        }
        return f[x][y]=mx;
    }
    int solve(vector<vector<int>>& g) {
        if (g.empty() || g[0].empty()) return 0;
        n=g.size(), m=g[0].size();
        vector<vector<int>> f(m, vector<int>(n, 0));
        for (int i=0; i<n; i++)
        for (int j=0; j<m; j++)
            ans=max(ans,dfs(i,j,f,g));
        return ans;
    }
};

140. 矩阵乘法

https://www.nowcoder.com/practice/bf358c3ac73e491585943bac94e309b0?tpId=117&&tqId=36042&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:线性代数知识,你不会就是不会

class Solution {
public:
    vector<vector<int> > solve(vector<vector<int> >& a, vector<vector<int> >& b) {
        int n=a.size();
        vector<vector<int>> c(n,vector<int>(n,0));
        for (int i=0; i<n; i++)
        for (int j=0; j<n; j++)
        for (int k=0; k<n; k++) {
            c[i][j]+=a[i][k]*b[k][j];
        }
        return c;
    }
};

141. 最长重复子串

https://www.nowcoder.com/practice/4fe306a84f084c249e4afad5edf889cc?tpId=117&&tqId=36041&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:枚举长度+合法性检测

class Solution {
public:
    bool valid(int l, int len, string& s) {
        for (int i=l; i<l+len; i++) if (s[i]!=s[i+len])
            return false;
        return true;
    }
    int solve(string& s) {
        int n=s.size();
        for (int len=n/2; len>0; len--) {
            for (int i=0; i<=n-2*len; i++) {
                if (valid(i,len,s))
                    return 2*len;
            }
        }
        return -1;
    }
};

142. 随时找到数据流的中位数

https://www.nowcoder.com/practice/8c5e99acb1fa4bc3a342cd321100c0cd?tpId=117&&tqId=35272&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:两个堆

class Solution {
public:
    priority_queue<int, vector<int>, greater<int>> minQ;
    priority_queue<int> maxQ;
    void addNum(int x) {
        maxQ.push(x);
        minQ.push(maxQ.top()), maxQ.pop();
        if (minQ.size()>maxQ.size()+1)
            maxQ.push(minQ.top()), minQ.pop();
    }
    double findMedian() {
        if (minQ.empty()) return -1;
        return minQ.size()!=maxQ.si***Q.top() : (minQ.top()+maxQ.top())*0.5;
    }
    vector<double> flowmedian(vector<vector<int> >& ops) {
        vector<double> ans;
        for (auto& op : ops) {
            if (op[0]==1) {
                addNum(op[1]);
            } else { //查询
                ans.push_back(findMedian());
            }   
        }
        return ans;
    }
};

143. 划分链表

https://www.nowcoder.com/practice/1dc1036be38f45f19000e48abe00b12f?tpId=117&&tqId=34944&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:双指针+细节,因为最后如果b的next不为空的话,将会导致循环引用

class Solution:
    def partition(self , head , x ):
        dead1,dead2=ListNode(0),ListNode(0)
        a, b=dead1, dead2 #a是小于x的结点,b是所有大于等于x的结点

        while (head):
            if (head.val < x):
                a.next=head
                a=a.next
            else:
                b.next=head
                b=b.next
            head=head.next
        a.next=dead2.next
        b.next=None
        return dead1.next

144. LFU缓存结构设计

https://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1?tpId=117&&tqId=35016&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:map+双向链表

import java.util.*;
public class Solution {
    public class LFUCache {

        private class Node {
            int k;
            int v;
            int count;
            public Node(int k, int v) {
                this.k = k;
                this.v = v;
                count = 1;
            }
        }

        private int size;
        private int maxSize;
        private Map<Integer, Node> key2node;
        private Map<Integer, LinkedList<Node>> count2list;

        public LFUCache(int maxSize) {
            this.maxSize = maxSize;
            size = 0;
            key2node = new HashMap<>();
            count2list = new HashMap<>();
        }

        public void set(int k, int v) {
            if (key2node.containsKey(k)) {
                key2node.get(k).v = v;
                get(k);
                return;
            }
            Node node = new Node(k, v);
            if (!count2list.containsKey(node.count)) count2list.put(node.count, new LinkedList<>());
            LinkedList<Node> list = count2list.get(node.count);
            list.addFirst(node);
            key2node.put(k, node);
            size++;
            if (size > maxSize) {
                key2node.remove(list.getLast().k);
                list.removeLast();
                size--;
            }
        }

        public int get(int k) {
            if (!key2node.containsKey(k)) return -1;
            Node node = key2node.get(k);
            LinkedList<Node> oldList = count2list.get(node.count);
            oldList.remove(node);
            if (oldList.isEmpty()) count2list.remove(node.count);
            node.count++;
            if (!count2list.containsKey(node.count)) count2list.put(node.count, new LinkedList<>());
            LinkedList<Node> list = count2list.get(node.count);
            list.addFirst(node);
            return node.v;
        }
    }
    public int[] LFU(int[][] operators, int k) {
        LFUCache cache = new LFUCache(k);
        List<Integer> list = new ArrayList<>();
        for (int[] e : operators) {
            if (e[0] == 1) cache.set(e[1], e[2]);
            else list.add(cache.get(e[1]));
        }
        int[] res = new int[list.size()];
        for (int i = 0; i < res.length; i++) res[i] = list.get(i);
        return res;
    }
}

145. 丢棋子问题

https://www.nowcoder.com/practice/d1418aaa147a4cb394c3c3efc4302266?tpId=117&&tqId=35279&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking

思路:动态规划题,dp[i][j]为i个棋子下j次能够辨别的最大n值

class Solution {
public:
    int solve(int n, int k) {
        if(n < 1) return 0;
        if(k == 1)return n;
        int t = log2(n) + 1;
        if( k >= t)
            return t;
        vector<int>f(k+1,0);
        int cnt=0;
        while(f[k] < n) {
            ++cnt;
            for(int i = k;i > 0;--i)
                f[i] += f[i-1] + 1;
        }
        return cnt;
    }
};
全部评论

相关推荐

比亚迪汽车新技术研究院 硬件工程师 总包21左右 硕士
点赞 评论 收藏
分享
牛客963010790号:为什么还要收藏
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务