力扣题库
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 == ''