华为面试手撕代码 leetcode 上重点题 附C++解法

剑指18 删除链表的节点

ListNode* deleteNode(ListNode* head, int val) {
        if(!head) return head;
        if(head->val == val) return head->next;
        ListNode* p=head;
        while(p->next && p->next->val != val){
            p=p->next;
        }
        if(p->next && p->next->val == val)  p->next = p->next->next;
        return head;
    }

剑指52 两个链表的第一个公共节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/*走过你来时的路,直到我们相遇*/
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
         ListNode* l1=headA;
         ListNode* l2=headB;
         while(l1!=l2){
    
    
            l1= l1!=NULL? l1->next:headB;
            l2= l2!=NULL? l2->next:headA;
         }
         return l1;    
    }

面试题 02.02. 返回倒数第 k 个节点

int kthToLast(ListNode* head, int k) {
    
    
       ListNode* slow=head, *fast=head;
       while(--k)
         fast=fast->next;
       while(fast!=NULL&&fast->next!=NULL){
    
    
           slow=slow->next;
           fast=fast->next;
       }
       return slow->val;
    }

344. 反转字符串

void reverseString(vector<char>& s) {
        
        int left=0;
        int right=s.size()-1;

        while(left<right){

        // swap (nums[left],nums[right])     
             char temp = s[left];
             s[left]=s[right];
             s[right]=temp;
             left++; 
             right--;
        }
    }

剑指 Offer 32 - I. 从上到下打印二叉树

  vector<int> levelOrder(TreeNode* root) {
     
       vector<int> res;
       if(root==nullptr) return res;
       queue<TreeNode*> q;

       q.push(root);            //根入队
       
       while(!q.empty()){       //此处不是 if ,是  while
           TreeNode* t=q.front();   //出队
           q.pop();
           res.push_back(t->val);  //出队时记录

           if(t->left)  q.push(t->left);      //左子节点入队
           if(t->right) q.push(t->right);      //右子节点入队
       }
    
       return res;
    } 

剑指 Offer 25. 合并两个排序的链表

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        
        if(l1==NULL)  return l2;
        if(l2==NULL)  return l1;
        if(l1->val<l2->val){
            l1->next=mergeTwoLists(l1->next,l2);
            return l1;
        }
        else{
            l2->next=mergeTwoLists(l1,l2->next);
            return l2;
        }

    }

783. 二叉搜索树节点最小距离

int prev, ans = INT_MAX;

    int minDiffInBST(TreeNode* root) {
        Inorder(root);
        return ans;
    }

    void Inorder(TreeNode* root) {
        if(root == NULL) return;
        Inorder(root->left);
        if(prev)                               // 若前置节点值不为空,则计算当前最小距离
            ans = min(ans, root->val-prev);       
        prev = root->val;                      // 更新前置节点值
        Inorder(root->right);
    }

剑指 Offer 50. 第一个只出现一次的字符

char firstUniqChar(string s) {

        if(s==" ")
          return ' ';
        unordered_map<char,int> m;
        for(int i=0;i<s.size();i++){
            m[s[i]]++;
        }
        for(int i=0;i<s.size();i++){
            if(m[s[i]]==1)
              return s[i];
        }
        return ' ';
    }

剑指 Offer 03. 数组中重复的数字

 int findRepeatNumber(vector<int>& nums){
       for(int i=0;i<nums.size();++i){
           while(i!=nums[i]){
                    if(nums[i]==nums[nums[i]]){
                        return nums[i];
                    }
                    else{
                        swap(nums[i],nums[nums[i]]);
                    }
           }
       }
       return 0;//不能少
   }

62. 不同路径

 int uniquePaths(int m, int n) {
    vector<vector<int>> dp(m+1,vector<int>(n+1));

    //为了接下来m,n从1起,申请了一个m+1*n+1的空间
    dp[0][1]=1;
    
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            dp[i][j]=dp[i-1][j]+dp[i][j-1];
        }
      }
    return dp[m][n];
    }

剑指 Offer 13. 机器人的运动范围

//计算两个坐标数字的和
    int sum(int i, int j){
        int sum=0;
        while(i!=0){
            sum+=i%10;
            i/=10;
        }
        while(j!=0){
            sum+=j%10;
            j/=10;
        }
        return sum;
    }

    int dfs(int i, int j, int m, int n, int k, vector<vector<int>> &visited){
         //i >= m || j >= n是边界条件的判断,k < sum(i, j)判断当前格子坐标是否
        // 满足条件,visited[i][j]判断这个格子是否被访问过

        if(i>=m || j>=n || k<sum(i,j) || visited[i][j] )
          return 0;
        //标注这个格子被访问过
        visited[i][j] = true;
        
        //沿着当前格子的右边和下边继续访问
        return 1 + dfs(i+1,j,m,n,k,visited)+ dfs(i,j+1,m,n,k,visited);

    }

    int movingCount(int m, int n, int k) {
        vector<vector<int>> visited(m,vector<int>(n,0));
        return dfs(0, 0, m, n, k, visited);  
    }

79. 单词搜索

bool exist(vector<vector<char>>& board, string word) {
        if(board.size()==0) return false;
        for(int i=0;i<board.size();i++){
            for(int j=0;j<board[0].size();j++){
                if(dfs(board,word,i,j,0)){
                    return true;
                }
            }
        }
         return false;
        
    }

    bool dfs(vector<vector<char>>&board,string & word,int i ,int j, int length ){
      if(i>=board.size() || j>=board[0].size() || i<0 || j<0 || length>=word.size() || word[length]!=board[i][j] ){
          return false;
      }
      if(length==word.size()-1 && word[length]==board[i][j]){
          return true;
      }
      
      char temp=board[i][j];
      board[i][j]='0';
      bool flag=dfs(board,word,i,j+1,length+1)||dfs(board,word,i,j-1,length+1)||dfs(board,word,i+1,j,length+1)||dfs(board,word,i-1,j,length+1);
      board[i][j]=temp;    // 标记过的点恢复原状,以便进行下一次搜索
      return flag;

     }
    

820. 单词的压缩编码

int minimumLengthEncoding(vector<string>& words) {
       
    int N = words.size();
    // 反转每个单词
    vector<string> reversed_words;
    for (string word : words) {
        reverse(word.begin(), word.end());
        reversed_words.push_back(word);
    }
    // 字典序排序    
    sort(reversed_words.begin(), reversed_words.end());

        int res = 0;
        for (int i = 0; i < N; i++) {
            if (i+1 < N && reversed_words[i+1].find(reversed_words[i]) == 0) {
                // 当前单词是下一个单词的前缀,丢弃
            } else {
                res += reversed_words[i].length() + 1; // 单词加上一个 '#' 的长度
            }
         }
      return res;

    }

剑指 Offer 63. 股票的最大利润//华为一面手撕

/*class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int m = prices.size();
        if(m == 0) return 0;
        int profit = 0;
        int price = INT_MAX;

        for(int i=0; i<m; i++){

            price=min(price, prices[i]);
            profit=max(profit, prices[i]-price);

        }
        return profit;   


    }
};*/
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size() <= 1)
            return 0;

        int min_price = prices[0], n = prices.size();
        vector<int> dp(n, 0);
        
        for(int i = 1; i < n; i++)
        {
            min_price = min(min_price, prices[i]);
            dp[i] = max(dp[i - 1], prices[i] - min_price);
        }
        return dp[n - 1];
    }
};

欢迎关注公众号,干货满满。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43499780/article/details/109000928