Leetcode[1/9/13] 两数之和、回文数、罗马数字转成整数 C/C++——第一天

两数之和

题目描述:[简单]

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 :

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因 nums[0] + nums[1] == 9 ,则返回 [0, 1] 。

C语言

系统默认代码块:

/**
 1. Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    
    
   
}

系统给出了4个参数,分别是 nums[](整数数组),numsize(该整数数组的个数),target(整数目标值,即两数之和),returnSize[](返回数组下标的个数)。

其中,returnSize一直困扰了我很久,我以为是将返回的数组下标放在这里面,因为看他也是个数组hhh。后来才知道是个数,那就是默认是2嘛。但是很有意思的是,我们一开始很容易把这个赋值写在if里面,其实是增加了时间复杂度的,放在外面不影响最后的测试,但是会在一定程度减少时间复杂度。

第一种思路:for + if 直接干+数组


int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    
    
    static int arr[2] = {
    
    0}; 
    *returnSize = 2;
       for(int i = 0 ; i < numsSize - 1; i++){
    
    
        for(int j = i+1 ; j < numsSize ; j++){
    
    
            if(nums[i] + nums[j] == target ){
    
    
                arr[0] = i;
                arr[1] = j;
                return arr;
           }      
        }
    }
     return 0;
}

用两个for对nums数组进行遍历,一开始我用的是:

扫描二维码关注公众号,回复: 15119258 查看本文章

for(int j = 1 ; j < numsSize ; j++)

那么在下一步if的时候,在判断语句那要加上 i != j 来甄别是否重复情况。增加了时间复杂度。如果变成

for(int j = i+1 ; j < numsSize ; j++)

就不用判断数组元素是否重复的情况。

————更新
可以用malloc动态分配内存,但是时间复杂度其实没有之前低。使用时注意malloc返回的是void\ *类型,但是题目要求int*,那么要进行强制转换,由于该数组只有两个元素,那么分配 int *2个空间,即

 int* twoSum(int* nums, int
 numsSize, int target, int* returnSize){
    
    
     int* arr = NULL;  
     *returnSize = 2;
        for(int i = 0 ; i < numsSize - 1; i++){
    
    
         for(int j = i+1 ; j < numsSize ; j++){
    
    
             if(nums[i] + nums[j] == target ){
    
    
                 arr = (int*) malloc(sizeof(int)*2); 
                 arr[0] = i;
                 arr[1] = j;
                 return arr;
            }      
        }
     }
      return 0; 
  } 
  

C++

系统默认代码块:

class Solution {
    
    
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    
    
        

    }
};

解题代码:

class Solution {
    
    
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    
    
        int i , j;
     for(i = 0 ; i < nums.size() - 1 ; i++){
    
    
         for(j = i+1 ;j < nums.size() ; j++){
    
    
             if (nums[i] + nums[j] == target)
             return {
    
     i , j };
         }

     }   
     return {
    
     i , j };
    };
};

其中,通过调用nums.size()可以获得数组的个数。而且这里的默认没有returnSize,可以直接return { i , j }; 不过时间复杂度比起c确实高了不少。

回文数

题目描述[简单]:
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1:

输入:x = 0
输出:true

C++

系统默认代码块:

class Solution {
    
    
public:
    bool isPalindrome(int x) {
    
    
    
    }
   
};

首先,本题没有限制是三位数,说明我们所有情况都要考虑到。那么对于负数,很显然因为负号的关系,不可能是回文数。那么我们一开始就要把他们区分开。
所有个位数为0的数字,反过来之后,都不是回文数,因为前面的0会省略到,但是注意一种特殊情况,0是回文数。

class Solution {
    
    
public:
    bool isPalindrome(int x) {
    
    
      if(x < 0 || (x % 10 == 0 && x != 0)){
    
    
          return false;
      }
      int num = 0 ;
      while(x > num){
    
    
          num = num * 10 + x % 10 ;
          x/=10;
      }
     if (x == num || x == (num / 10) ){
    
    
       return true;  
       }
    return NULL;
    } 
};

我采用的是只翻转一半,那么在while里面,只有原数小于翻转的数字,就可以停止翻转了。

对于数字从前看和从后看,要分奇数位和偶数位,如果是奇数位,那么最中间的那位可以不用反转,因为自己跟自己比肯定是一样的。所以在最后我们判断的条件分为两种,如果是奇数位我们要/10使得最中间那位数被消除掉,再比较是否相等。如果是偶数位,就可以直接判断。

C语言

bool isPalindrome(int x){
    
    
 if(x < 0 || (x % 10 == 0 && x != 0)){
    
    
          return false;
      }
      int num = 0 ;
      while(x > num){
    
    
          num = num * 10 + x % 10 ;
          x/=10;
      }
     if (x == num || x == (num / 10) ){
    
    
       return true;  
       }
    return NULL;
}

罗马数字转整数

题目说明[简单]:

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个罗马数字,将其转换成整数。

C++

class Solution {
    
    
public:
    int romanToInt(string s) {
    
    
    int num=0;
    //IV,IX 4,9; XL,XC 40,90;CD,CM 400,900
    for(int i=0;i<s.size();i++){
    
    
        if(s[i]=='V') 
          num+=5;
        if(s[i]=='L') 
          num+=50;
        if(s[i]=='D') 
          num+=500;
        if(s[i]=='M') 
          num+=1000;
        if(s[i]=='I'){
    
    
            if(s[i+1]=='V'||s[i+1]=='X') //I放在V和X左边,但是同时要-1
               num-=1;
            else num+=1;
        }
        if(s[i]=='X'){
    
    
            if(s[i+1]=='L'||s[i+1]=='C') //X放在L和C左边,同时-10
               num-=10;
            else num+=10;
        }
        if(s[i]=='C'){
    
    
            if(s[i+1]=='D'||s[i+1]=='M') //C放在D和M左边,同时-100
              num-=100;
            else num+=100;
        }
    }
    return num;
    }
};

猜你喜欢

转载自blog.csdn.net/Lailalalala/article/details/125980605