troubleasy

导航

 

2. 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

 

示例 1:

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

 

提示:

  • 每个链表中的节点数在范围 [1, 100]
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零
  • 两数相加最方便的方式便是,对位数较少的数在末位补0使两数位数相同,之后同步遍历计算相加取余和进位。
      1 /**
      2 
      3  * Definition for singly-linked list.
      4 
      5  * struct ListNode {
      6 
      7  *     int val;
      8 
      9  *     ListNode *next;
     10 
     11  *     ListNode() : val(0), next(nullptr) {}
     12 
     13  *     ListNode(int x) : val(x), next(nullptr) {}
     14 
     15  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     16 
     17  * };
     18 
     19  */
     20 
     21 class Solution {
     22 
     23 public:
     24 
     25     ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {    
     26 
     27         //分段法 
     28 
     29     /*
     30 
     31         if(l1==nullptr)return l2;
     32 
     33         if(l2==nullptr)return l1;
     34 
     35         int nval=0;
     36 
     37         ListNode *p;
     38 
     39         p=l1;
     40 
     41         while(p!=nullptr&&l2!=nullptr)
     42 
     43         {
     44 
     45             int v=p->val+l2->val+nval;
     46 
     47             nval=v/10;
     48 
     49             p->val=v%10;
     50 
     51            if(p->next!=nullptr&&l2->next!=nullptr)
     52 
     53           {  p=p->next;
     54 
     55             l2=l2->next;
     56 
     57 
     58           }else break;
     59 
     60         }
     61 
     62         if(l2->next!=nullptr)
     63 
     64         {
     65 
     66             p->next=l2->next; 
     67 
     68         }
     69 
     70         while(p->next!=nullptr){
     71 
     72             p=p->next;
     73 
     74             int v=p->val+nval;
     75 
     76             nval=v/10;
     77 
     78             p->val=v%10;
     79 
     80         }
     81 
     82         if(nval==1) p->next=new ListNode(1);
     83 
     84         return l1;
     85 
     86     }
     87 
     88     */
     89 
     90     //补0
     91 
     92     int len1=0,len2=0;
     93 
     94     ListNode*p1=l1,*p2=l2;
     95 
     96     while(p1->next!=nullptr)
     97 
     98     {
     99 
    100         len1++;
    101 
    102         p1=p1->next;
    103 
    104     }
    105 
    106     while(p2->next!=nullptr)
    107 
    108     {
    109 
    110         len2++;
    111 
    112         p2=p2->next;
    113 
    114     }
    115 
    116     //p1=l1;p2=l2;
    117 
    118     if(len1<len2){
    119 
    120         for(int i=0;i<len2-len1;i++)
    121 
    122         {
    123 
    124             p1->next=new ListNode(0);
    125 
    126             p1=p1->next;
    127 
    128         }
    129 
    130     }
    131 
    132     if(len1>len2){
    133 
    134         for(int i=0;i<len1-len2;i++)
    135 
    136         {
    137 
    138             p2->next=new ListNode(0);
    139 
    140             p2=p2->next;
    141 
    142         }
    143 
    144     }
    145 
    146     int len=(len1>=len2)?len1:len2;
    147 
    148     p1=l1;p2=l2;
    149 
    150     int nval=0;
    151 
    152     while(p2!=nullptr)
    153 
    154     {
    155 
    156         int v=p1->val+p2->val+nval;
    157 
    158         nval=v/10;
    159 
    160         p1->val=v%10;
    161 
    162         if(p1->next!=nullptr)
    163 
    164         {
    165 
    166             p1=p1->next;
    167 
    168             p2=p2->next;
    169 
    170         }else break;
    171 
    172     }
    173 
    174     if(nval==1) p1->next=new ListNode(1);
    175 
    176     return l1;
    177 
    178     }
    179 
    180 
    181 };
    View Code

 

4. 寻找两个正序数组的中位数

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。

进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?

 

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2

示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

示例 3:

输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000

示例 4:

输入:nums1 = [], nums2 = [1]
输出:1.00000

示例 5:

输入:nums1 = [2], nums2 = []
输出:2.00000

 

提示:

  • nums1.length == m
  • nums2.length == n
  • 0 <= m <= 1000
  • 0 <= n <= 1000
  • 1 <= m + n <= 2000
  • -106 <= nums1[i], nums2[i] <= 106

     原理跟选取第k小元素类似,这里的k表示要求的中位数的位置。每次从两个序列分别取前k/2个数,比较两个第k/2个数的大小,将较小数对应序列的前k/2个数排除,因为这几个数一定包含在要求的中位数之前。下轮再分别取(k-k/2)/2个数,直到k=1;

  • 一个技巧:计算序列的中位数,在不确定奇偶时 ,有通式num[mid]=(num[(n+1)/2]+nums[(n+2)/2])/2,n为序列长度。

     1 class Solution {
     2 public:
     3     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
     4         //第k小元素
     5         //每次比较两个余下序列的中间值大小,排除掉其中较小元素的左侧元素,移动指针;
     6         //考虑序列各自的奇偶
     7         int m=nums1.size(),n=nums2.size();
     8         return (findKth(nums1,0,nums2,0,(m+n+1)/2)+findKth(nums1,0,nums2,0,(m+n+2)/2))/2.0;
     9 
    10 
    11     }
    12     int findKth(vector<int >&nums1,int i,vector<int >&nums2,int j,int k)
    13     {
    14          if(i>=nums1.size())return nums2[j+k-1];
    15         if(j>=nums2.size())return nums1[i+k-1];
    16         if(k==1){
    17         
    18              return std::min(nums1[i],nums2[j]);
    19         }
    20         int mid1=(i+k/2-1>=nums1.size())?INT_MAX:nums1[i+k/2-1];
    21         int mid2=(j+k/2-1>=nums2.size())?INT_MAX:nums2[j+k/2-1];
    22         if(mid1<mid2)
    23         return findKth(nums1,i+k/2,nums2,j,k-k/2);
    24         return findKth(nums1,i,nums2,j+k/2,k-k/2);
    25     }
    26 };
    View Code

     

 

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

 

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

示例 3:

输入:s = "a"
输出:"a"

示例 4:

输入:s = "ac"
输出:"a"

 

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母(大写和/或小写)组成
 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4        //最大回文子串
 5         //从center向两边延伸元素相等;center为元素或者空格
 6         int start=0,end=0;
 7         for(int i=0;i<s.length();i++)
 8         {
 9             int len1=expandCenter(s,i,i);//长度是奇数
10             int len2=expandCenter(s,i,i+1);//长度是偶数
11             int len=(len1>=len2)?len1:len2;
12             if(len>(end-start+1))
13             {
14                 start=i-(len-1)/2;
15                 
16                 end=i+len/2;
17             }
18         }
19         return s.substr(start,end-start+1);
20     
21     }
22     int expandCenter(string s,int left,int right)
23     {
24         while(left>=0&&right<s.length()&&s[left]==s[right])
25         {
26             left--;right++;
27         }
28         return (right-left)-1;
29     }
30 };

 

posted on 2021-10-12 18:09  troubleasy  阅读(29)  评论(0)    收藏  举报