LeetCode刷题day09

简介: LeetCode刷题day09

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

165971dd6395447eaa77977a71194b01.png


示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]


示例 2:

输入:digits = ""
输出:[]


示例 3:

输入:digits = "2"
输出:["a","b","c"]


方法一:递归回溯

每次根据一个数字然后获得对应的一个字母,进行下一个数字,直到达到字符串长度.然后回溯尝试下一个相同数字对应不同的字母.

参考代码1

#include<bits/stdc++.h>
using namespace std;
vector<string> ans;
void dfs(string &s,int num);
vector<string> letterCombinations(string digits) {
  if(digits=="") {
    return {};
  }
  dfs(digits,0);
  return ans;
}
void dfs(string s,int num) {//这里不能使用引用,因为这次的字符串等到回溯回来 
  if(num==s.size()) { //结束条件
    ans.push_back(s);
    return;
  }
  switch(s[num]) {
    case '2':
      s[num] = 'a';
      dfs(s,num+1);
      s[num] = 'b';
      dfs(s,num+1);
      s[num] = 'c';
      dfs(s,num+1);
      break;
    case '3':
      s[num] = 'd';
      dfs(s,num+1);
      s[num] = 'e';
      dfs(s,num+1);
      s[num] = 'f';
      dfs(s,num+1);
      break;
    case '4':
      s[num] = 'g';
      dfs(s,num+1);
      s[num] = 'h';
      dfs(s,num+1);
      s[num] = 'i';
      dfs(s,num+1);
      break;
    case '5':
      s[num] = 'j';
      dfs(s,num+1);
      s[num] = 'k';
      dfs(s,num+1);
      s[num] = 'l';
      dfs(s,num+1);
      break;
    case '6':
      s[num] = 'm';
      dfs(s,num+1);
      s[num] = 'n';
      dfs(s,num+1);
      s[num] = 'o';
      dfs(s,num+1);
      break;
    case '7':
      s[num] = 'p';
      dfs(s,num+1);
      s[num] = 'q';
      dfs(s,num+1);
      s[num] = 'r';
      dfs(s,num+1);
      s[num] = 's';
      dfs(s,num+1);
      break;
    case '8':
      s[num] = 't';
      dfs(s,num+1);
      s[num] = 'u';
      dfs(s,num+1);
      s[num] = 'v';
      dfs(s,num+1);
      break;
    case '9':
      s[num] = 'w';
      dfs(s,num+1);
      s[num] = 'x';
      dfs(s,num+1);
      s[num] = 'y';
      dfs(s,num+1);
      s[num] = 'z';
      dfs(s,num+1);
      break;
  }
}
int main() {
  string digits = "23";
  letterCombinations(digits);
  for(int i = 0;i < ans.size();i++){
    cout<<ans[i]<<endl;
  }
  cout<<ans.size()<<endl;
  return 0;
}

方法二:队列

思路:


先将输入的digits中的第一个数字对应的字母入队,假设此时队列中的元素个数为len.

然后出去一个元素和第二个数字对应的每一个字母组合然后入队…之后再出去一个元素和第二个数字对应的字母组合入队…之后再…

等待len个元素都进行过该操作,则进行下一个数字;直到遍历到digits的结尾.最后队列中的元素即为所求.


参考代码2

#include<bits/stdc++.h>
using namespace std;
string phone[]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
queue<string> Q; 
vector<string> ans;
vector<string> letterCombinations(string digits) {
  string temp,s1,s2;
  int pos,len;
  if(digits==""){
    return {};
  }
  for(int i = 0;i < digits.size();i++){
     pos = digits[i]-'0';
     s1 = phone[pos];//当前数字对应的序列 
    if(!i){//第一个数字 
      for(int j = 0;j < s1.size();j++){
        temp = "";
        temp+=s1[j];
        Q.push(temp);
      } 
    }else{//如果不是第一个字符. 弹出一个,拼接新的字符,重新放入. 
      len = Q.size();
       for(int j = 0;j < len;j++){//
        s2 = Q.front();
        Q.pop();
        for(int k = 0; k < s1.size();k++){
          temp = "";
          temp += s2;
          temp+=s1[k];
          Q.push(temp);
         } 
       } 
    }
  }
  while(!Q.empty()){
    temp = Q.front();
    Q.pop();
    ans.push_back(temp);
  }
  return ans;
}
int main() {
  string digits = "";
  letterCombinations(digits);
  for(int i = 0;i < ans.size();i++){
    cout<<ans[i]<<endl;
  }
  cout<<ans.size()<<endl;
  return 0;
}

时间复杂度:

7512a2f71e004ed398baab9f6d4ff230.png


19. 删除链表的倒数第 N 个结点


给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

进阶:你能尝试使用一趟扫描实现吗?

示例 1:

23ec7597a118492d88f9165e7a6527ba.png

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

输入:head = [1], n = 1
输出:[]

示例 3:

输入:head = [1,2], n = 1
输出:[1]


方法一

链表的基本使用:


逆向删除第n个节点,相当于正向删除第m = cnt-n+1个节点.

删除一个节点,则需要一个辅助指针指向当前节点的前一个节点.

如果当前只有一个节点,则直接进行删除(因为n>=1)

否则用辅助指针p找到m-1个节点.然后修改指针的指向:p->next = p->next->next;


参考代码

#include<bits/stdc++.h>
using namespace std;
//https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/ 
//链表的基本使用 
struct ListNode {
  int val;
  ListNode *next;
  ListNode() : val(0), next(nullptr) {}
  ListNode(int x) : val(x), next(nullptr) {}
  ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode* removeNthFromEnd(ListNode* head, int n) {
  ListNode* p = head;
  int cnt = 1;
  while(p->next!=NULL){
    p = p->next;
    cnt++;
  }
  int m = cnt - n + 1;//正向删除 cng=5  n=1  5  n=2 4   cnt+1-n 
  p = head;
  if(m==1){
    return p->next;
  }
  for(int i = 1;i <= m-2;i++){
    p = p->next;
  }
  p->next = p->next->next;
  return head; 
}
int main(){
  return 0;
}

方法二:

快慢指针

15280163cacf499888e66e71ef04ddf6.png

  • 时间复杂度:O(L),其中 L是链表的长度。
  • 空间复杂度:O(1)。

参考代码2

#include<bits/stdc++.h>
using namespace std;
//https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/
//链表的基本使用
struct ListNode {
  int val;
  ListNode *next;
  ListNode() : val(0), next(nullptr) {}
  ListNode(int x) : val(x), next(nullptr) {}
  ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode* removeNthFromEnd(ListNode* head, int n) {
  if(head->next==NULL){//如果只有一个结点,则删除的必定是头结点因为n>1 
    return NULL;
  }
  ListNode *fast = head,*slow = head;
  for(int i = 0;i < n;i++){
    fast = fast->next;
  }
  if(!fast){//如果移动n位后为null,说明删除的是第一个节点 
    return head->next;
  }
  while(fast->next){
    fast = fast->next;
    slow = slow->next;
  } 
  slow->next = slow->next->next;
  return head;//返回第一个节点对应的指针. 
}


相关文章
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
260 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
169 6
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
182 4
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
371 2
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
277 3
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
350 1
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
350 7
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
196 5
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
161 4
|
Python
【Leetcode刷题Python】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
Leetcode题目"剑指 Offer 21. 调整数组顺序使奇数位于偶数前面"的两种Python解决方案,一种是使用双端队列调整数组顺序,另一种是使用双指针法将奇数移到数组前半部分,偶数移到后半部分。
146 4

热门文章

最新文章