力扣题目练习

1.两数之和

1.1.C语言——暴力破解

int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int i=0,j=0;
    *returnSize = 2;
    //printf("%d",sizeof(nums));  这里sizeof不行,每个数组的sizeof都是8;
    //sizeof如果你一开始就定义了数组的大小,那么不管你插入多少个元素,求出来的结果永远是你定义的数组大小。
    //如果你没有定义数组大小,那么算出来的就是你实际赋值的数组大小。
    int* p = (int*)malloc(sizeof(int)*2);
    for(i=0;i<numsSize-1;i++){
      for(j=i+1;j<numsSize;j++){
          if(nums[i]+nums[j]==target){
             p[0]=i;
             p[1]=j;
          } 
      }
    }
    return p;
}

1.2C++——暴力破解

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 {};
    }
};

2.两数相加

2.1C++(第一种)

/**
 * Definition for singly-linked list.
 * 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) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *result = new ListNode();   
        result->val=0;
        result->next=NULL;
        ListNode *result_head = new ListNode();
        result_head->next = result;
        int temp=0;
        while(l1 != NULL ||l2 !=NULL)  //分为l1!=null,l2=null && l1=null,l2!=null &&l1!=null,l2!=null
        {
            if(l1==NULL){
                l1 = new ListNode(0); 
            }
            if(l2==NULL){
                l2 = new ListNode(0); 
            }
            temp=(result->val+l1->val+l2->val)/10;
            result->val=(result->val+l1->val+l2->val)%10;
            //需要进位时
            if(temp>=1){
            ListNode *newnode = new ListNode();
            result->next=newnode;
            result->next->val=temp;
            }
            //下一位计算
            if(l1->next==NULL && l2->next != NULL){
            ListNode *newnode = new ListNode(0);
            l1->next=newnode;
            }
            if(l2->next==NULL && l1->next != NULL){
            ListNode *newnode = new ListNode(0);
            l2->next=newnode;
            }
            if(l2->next!=NULL && l2->next !=NULL && temp==0){ 
            //当未进位时,创建result->next新结点;防止出现未进位时,结点未被创造
            ListNode *newnode = new ListNode();
            result->next=newnode;
            }
            //向后移一位
            result=result->next;
            l1=l1->next;
            l2=l2->next;
        }
      return result_head->next;
    }
};

2.2C++(第二种)

/**
 * Definition for singly-linked list.
 * 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) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *result = new ListNode();   
        result->val=0;
        result->next=NULL;
        ListNode *result_bak = new ListNode();
        result_bak->next = result;
        int sum=0;
        int tmpl1,tmpl2 = 0;
        int carr = 0;
        while(l1 != 0 || l2 != 0){
            //分为几种情况一种是两个里面都有值,则直接加,判断是否大于10,如果大于10则进位,如果不大于10看一看下一个是否有值,如果
            //有值则建立新的节点如果没有则什么也不用做
            // tmpl1 = 0 ? l1 == NULL : l1->val;
            // tmpl2 = 0 ? l2 == NULL : l2->val;
            if(l1 != 0){
                tmpl1 = l1->val;
            }
            else if(l1 == 0){
                tmpl1 = 0;
            }
            if(l2 != 0){
                tmpl2 = l2->val;
            }
            else if(l2 == 0){
                tmpl2 = 0;
            }
            result->val = result->val + tmpl1 + tmpl2;
            carr = (result->val) / 10;
            result->val=(result->val) % 10;
            if(carr >= 1){
                ListNode *newnode = new ListNode(carr); 
                result->next=newnode;
            }
            //如果没有进位,看下一个是否有值,如果有值建立一个新节点,如果没有值则什么也不用干
            else if(l1 != 0 || l2 != 0){//若l1、l2下一个不为空
                if(l1 != 0){
                    if(l1->next != 0){
                        ListNode *newnode = new ListNode(0); 
                        result->next=newnode;
                    }
                }
                // puts("aaa");
                if(l2 != 0){
                    if(l2->next != 0){
                        ListNode *newnode = new ListNode(0); 
                        result->next=newnode;
                    }
                }
                if(l1 != 0 && l2 != 0){
                    if(l1->next !=0 && l2->next != 0){
                        ListNode *newnode = new ListNode(0); 
                        result->next=newnode;
                    }
                }
            }
            printf("%d %d %d\n",tmpl1,tmpl2,result->next);
            result=result->next;
            if(l1 == 0){
                l1 = 0;
            }
            else if(l1 != 0){
                l1 = l1->next;
            }
            if(l2 == 0){
                l2 = 0;
            }
            else if(l2 != 0){
                l2 = l2->next;
            }
            // return result_bak->next;
        }
      return result_bak->next;
    }
};

3. 删除有序数组中的重复项

3.1c++

看评论里别人代码学习。例如nums = [0,0,1,1,1,2,2,3,3,4],这段代码的大概思路是i、j从第一位开始,pre保存为num[0]。若未遇到重复数字的时候,i、j都向后移动一个位置。若遇到第i个数组值等于pre的值,i就往后一直移动到第一个不等于pre的位置。在这个例子中,即i先移动到nums[2]。然后,将nums[i]的值赋值给nums[j],即将2覆盖第一个0。j的变化是按顺序1、2、3移动,i是通过continue跳过后面的语句移动到第一个不重复的地方。

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

可将上诉代码简化为下面代码

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

4.回文数

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是。

4.1C++,将整数转为字符串

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0) return false;
        string str=to_string(x);
        for(int j=0;j<str.length()/2;j++){
            if(str[j]!=str[str.length()-j-1]){
                return false;
            }
        }
        return true;
    }
};

4.2C++,不将整数转为字符串

将数字倒过来计算一遍,看是否与原数相等。

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0) return false;
        long long number=x;
        long long sum=0;
        while(x>0){
            sum=sum*10+x%10;
            x=x/10;
        }
        if(sum==number)
            return true;
        return false;
    }
};

5.合并两个有序链表

5.1建立一个新的头来放排好序的结点。

在这里插入图片描述

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        struct ListNode* head=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode* tail=head;
        if(list1==NULL) return list2;
        if(list2==NULL) return list1;
        else{
            while(list1!=NULL&&list2!=NULL){//当两者都不为空时,进行大小比较
                if(list1->val<list2->val){
                    tail->next=list1;
                    list1=list1->next;
                }
                else{
                    tail->next=list2;
                    list2=list2->next;
                }
                tail=tail->next;
                        
            }
            //将链表剩下的部分连接过去
            if(list1==NULL){tail->next=list2;}
            if(list2==NULL){tail->next=list1;}
            return head->next;   
        }
    }
};

5.2递归的方法

看评论里的大佬们用递归写的,我这脑子想不出来这些高级的办法。呜呜

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if(!list1) return list2;
        if(!list2) return list1;
        if(list1->val < list2->val) {
            list1->next = mergeTwoLists(list1->next, list2);
            return list1;
        }
        else {
            list2->next = mergeTwoLists(list1, list2->next);
            return list2;
        }
    }
};

6.有效的括号

6.1c++,用栈的方式。

遇见左边符号({[,入栈。遇见右边符号)}],首先检查栈顶是否为对应的左边符号,若不是,返回false,若是则出栈。注意申请栈空间时,应该比字符串长度大1,不然在计算时容易出现错误。

class Solution {
public:
    bool isValid(string s) {
        int i=1;
        int k=s.length()+1;
        char stack[k];
        for(int l=0;l<s.length();l++){
            if(s[l]=='('||s[l]=='['||s[l]=='{'){//入栈
            stack[i]=s[l];
            i++;
            }
            if(s[l]==')') {
                if(stack[i-1]!='(') return false;
                i--;//出栈
            }
            if(s[l]==']') {
            if(stack[i-1]!='[') return false;
                i--;
            }
            if(s[l]=='}') {
                if(stack[i-1]!='{') return false;
                i--;
            }
        }
        if(i!=1) return false;
        return true;
    }
};

写完一看评论的大佬写的,只有膜拜。

6.1.1c++的stack用法。

这个文章很全http://t.csdnimg.cn/zy1g5

①stack

stack<储存的类型> 容器名。如:
储存int型数据的栈 stack s;
储存double型数据的栈 stack s;
储存string型数据的栈 stack s;
储存结构体或者类的栈 stack<结构体名> s;
同样也可以定义数组,如:储存int型数据的栈 stack s[n];
stack常用的成员函数:

empty() //堆栈为空则返回真,即返回1;不为空时返回0 
pop() //移除栈顶元素 
push() //在栈顶增加元素 
size() //返回栈中元素数目 
top() //返回栈顶元素 
②string

string也是一种栈结构,可以使用以下方法:

empty() //堆栈为空则返回真 
pop_back() //移除栈顶元素 
push_back() //在栈顶增加元素 
size() //返回栈中元素数目 
back() //返回栈顶元素 
③比string应用更广泛vector

string只能存储char类型的,而vector能存储所有类型的数据,像int、double、结构体、类等等

empty() //堆栈为空则返回真 
pop_back() //移除栈顶元素 
push_back() //在栈顶增加元素 
size() //返回栈中元素数目 
back() //返回栈顶元素 

所以可以用stack类型来解题

class Solution {
public:
    bool isValid(string s) {
        stack<char> sta;
        for(int l=0;l<s.length();l++){
            if(s[l]=='('||s[l]=='['||s[l]=='{'){
            sta.push(s[l]);//入栈
            }
            if(s[l]==')') {
                if(sta.empty()||sta.top()!='(') return false;//判断栈是否为空;判断栈顶元素
                sta.pop();//出栈
            }
            if(s[l]==']') {
                if(sta.empty()||sta.top()!='[') return false;
                sta.pop();
            }
            if(s[l]=='}') {
                if(sta.empty()||sta.top()!='{') return false;
                sta.pop();
            }
        }
        if(!sta.empty()) return false;//判断栈是否为空
        return true;
    }
};

6.2 python

评论学到的replace方法。对于{()}这种情况,是先识别到了(),将其变为空后,之后再次识别到{}。

在Python中,字符串的replace方法用于替换字符串中的子字符串。该方法有两个参数:
str.replace(old, new[, count])
old: 要被替换的子字符串。
new: 用于替换的新字符串。
count(可选参数): 指定替换的次数。如果提供了这个参数,那么只有前 count 次出现的子字符串会被替换。

所以可用以下方式进行判断

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        while '{}' in s or '()' in s or '[]' in s:
            s = s.replace('{}', '')
            s = s.replace('[]', '')
            s = s.replace('()', '')
        return s == ''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值