给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
void rotate(int* nums, int numsSize, int k) {
k=k%numsSize;
if(k>numsSize&&numsSize==1)
return;
if(k>numsSize&&numsSize==2){
int tmp=*nums;
*nums=nums[1];
nums[1]=tmp;
return;
}
int* newnums = (int*)malloc(sizeof(int) * numsSize * 2);
for (int j = 2;j > 0;--j) {
for (int i = 0;i < numsSize;++i) {//将数组复制两次到新数组
if (j == 2) {
newnums[i] = nums[i];
}
else {
newnums[numsSize + i] = nums[i];
}
}
}
for (int i = 0;i < numsSize;i++) {
nums[i] = newnums[numsSize+i-k];
}
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/add-to-array-form-of-integer
整数的 数组形式 num 是按照从左到右的顺序表示其数字的数组。
例如,对于 num = 1321 ,数组形式是 [1,3,2,1] 。给定 num ,整数的 数组形式 ,和整数 k ,返回 整数 num + k 的 数组形式 。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* addToArrayForm(int* num, int numSize, int k, int* returnSize) {
int* res = malloc(sizeof(int) * fmax(10, numSize + 1));//fmax返回两者较大值
*returnSize = 0;//返回一个数组指针 但是returnsize的意思是返回的长度是多少
for (int i = numSize - 1; i >= 0; --i) {
int sum = num[i] + k % 10;//将个位和个位的数字相加
k /= 10;
if (sum >= 10) {//如果在这个位置出现了进位
k++;
sum -= 10;
}
res[(*returnSize)++] = sum;//赋值给返回数组并数组返回长度自增
}
for (; k > 0; k /= 10) {//如果k还大于零 那么就说明还没有加完 但是原数组的值已经加完了 那么就直接将这个位数的值赋值给res数组中
res[(*returnSize)++] = k % 10;
}
for (int i = 0; i < (*returnSize) / 2; i++) {//将数组进行反转
int tmp = res[i];
res[i] = res[(*returnSize) - 1 - i];
res[(*returnSize) - 1 - i] = tmp;
}
return res;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/merge-sorted-array
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
//自己的解答
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
int count=0;
int i=0,j=0;
if(m==0){//nums1是没有元素参加时
for(;j<n;j++)
nums1[i++]=nums2[j];
return;
}
int arr[m];
for(i=0;i<m;i++){//nums1有元素参加时
arr[i]=nums1[i];
}
i=0;
while(i<m&&j<n){
if(arr[i]<nums2[j])
nums1[count++]=arr[i++];
else
nums1[count++]=nums2[j++];
}
if(i!=m){//判断nums1剩余还是nums2剩余
for(;i<m;i++)
nums1[count++]=arr[i];
}else{
for(;j<n;j++)
nums1[count++]=nums2[j];
}
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-element/
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
int removeElement(int* nums, int numsSize, int val){
int count=0;//count记录有效的数组数目
for(int i=0;i<numsSize;i++){
if(val!=nums[i]){
nums[count++]=nums[i];
}
}
return count;
}
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @return ListNode类
*/
#include
struct ListNode* deleteDuplication(struct ListNode* pHead) {
// write code here
typedef struct ListNode ListNode;
if(pHead==NULL||pHead->next==NULL)//空串则返回该头节点
return pHead;
ListNode* preHead=(ListNode*)malloc(sizeof(ListNode));
preHead->next=pHead;
ListNode* pre =preHead;//新链表的工作节点
ListNode* cur=pHead;//遍历工作结点
while (cur) {
ListNode* nextDifferent=cur->next;
while (nextDifferent&&nextDifferent->val==cur->val)//找到链表中两个不同节点
nextDifferent=nextDifferent->next;
if(cur->next==nextDifferent){//如果链表没有中间的相同结点,那么就直接链接上
pre->next=cur;
pre=cur;
cur=nextDifferent;
}else {//如果中间有相同的中间结点,那么工作指针直接将这一段跳过
cur=nextDifferent;
}
}
pre->next=cur;
return preHead->next;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/insertion-sort-list
给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。
插入排序 算法的步骤:
插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。
下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。
对链表进行插入排序。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* insertionSortList(struct ListNode* head){
typedef struct ListNode ListNode;
ListNode* dummy=(ListNode*)malloc(sizeof(ListNode));//返回的新链表
dummy->next=NULL;
ListNode* cur=head;
while(cur){
ListNode* prev=dummy;
ListNode* next=cur->next;
while(prev->next!=NULL&&prev->next->val <= cur->val){//边遍历 边比较
prev=prev->next;
}
cur->next=prev->next;
prev->next=cur;
cur=next;
}
return dummy->next;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reverse-linked-list/description/
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
typedef struct ListNode ListNode;
ListNode *p;
p=(ListNode*)malloc(sizeof(ListNode));
p->next=NULL;
while(head!=NULL){
ListNode* tmp=head;
head=head->next;
tmp->next=p->next;
p->next=tmp;
}
head=p->next;
free(p);
return head;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/middle-of-the-linked-list/description/
给你单链表的头结点 head ,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
typedef struct ListNode ListNode;
ListNode* p=head;
int count=0;
while(p!=NULL){
p=p->next;
++count;
}
count=count/2;
while(count>0){
head=head->next;
--count;
}
return head;
}
输入一个链表,输出该链表中倒数第k个结点。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pListHead ListNode类
* @param k int整型
* @return ListNode类
*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
typedef struct ListNode ListNode;
ListNode* p=pListHead;
ListNode* q=pListHead;
int count=k;
while (count>0&&p!=NULL) {
p=p->next;
--count;
}
if(count>0&&p==NULL){
q=p;
}
while (p!=NULL) {
p=p->next;
q=q->next;
}
return q;
}
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
typedef struct ListNode ListNode;
if(list1==NULL&&list2==NULL){
return list1;
}else if(list1==NULL&&list2!=NULL){
return list2;
}else if(list1!=NULL&&list2==NULL){
return list1;
}
ListNode *p;
p=(ListNode*)malloc(sizeof(ListNode));
ListNode *q=p;
while(list1!=NULL&&list2!=NULL){
if(list1->val<list2->val){
p->next=list1;
p=p->next;
list1=list1->next;
}else{
p->next=list2;
p=p->next;
list2=list2->next;
}
}
while(list1!=NULL){
p->next=list1;
p=p->next;
list1=list1->next;
}
while(list2!=NULL){
p->next=list2;
p=p->next;
list2=list2->next;
}
return q->next;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-linked-list-elements/
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:
输入:head = [], val = 1
输出:[]
示例 3:
输入:head = [7,7,7,7], val = 7
输出:[]
struct ListNode* removeElements(struct ListNode* head, int val){
while(head!=NULL&&head->val==val){
struct ListNode* tmp=head;
head=head->next;
free(tmp);
}
struct ListNode* cur=head;
while(cur!=NULL&&cur->next!=NULL){
if(cur->next->val==val){
cur->next=cur->next->next;
}else{
cur=cur->next;
}
}
return head;
}
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
typedef struct ListNode ListNode;
ListNode* dummyhead;
dummyhead=(ListNode*)malloc(sizeof(ListNode));
dummyhead->next=head;
ListNode *cur=dummyhead;
while(cur->next!=NULL){
if(cur->next->val==val){
ListNode* tmp=cur->next;
cur->next=cur->next->next;
free(tmp);
}else{
cur=cur->next;
}
}
return dummyhead->next;
}
来源:牛客网
链接:https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
#include
#include
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
// write code here
struct ListNode*head1,*head2,*tail1,*tail2;
head1=tail1=(struct ListNode*)malloc(sizeof(struct ListNode));
head2=tail2=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* cur=pHead;
while (cur) {
if(cur->val<x){
tail1->next=cur;
tail1=tail1->next;
}else{
tail2->next=cur;
tail2=tail2->next;
}
cur=cur->next;
}
tail1->next=head2->next;
tail2->next=NULL;
pHead=head1->next;
free(head1);
free(head2);
return pHead;
}
};
https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa?tpId=49&&tqId=29370&rp=1&ru=/activity/oj&qru=/ta/2016test/question-ranking
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例
1->2->2->1
返回:true
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
#include
#include
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
ListNode* dummy=(ListNode*)malloc(sizeof(ListNode));
dummy->next=A;
ListNode* fast=dummy;//快慢指针读取中间节点
ListNode* slow=dummy;
while (fast&&fast->next) {
fast=fast->next->next;
slow=slow->next;
}
ListNode* cur=slow->next;//工作指针
ListNode* next=cur->next;//工作指针的下一个位置
ListNode* pre=slow;//工作指针的上一个位置
slow->next=NULL;//防止成环,断链
while (1) {//将后半部分链表反转
cur->next=pre;
pre=cur;
if (next==NULL)
break;
cur=next;
next=cur->next;
}
ListNode* head=A;
ListNode* tail=cur;
while (tail!=slow) {
if(head->val!=tail->val)
return false;
tail=tail->next;
head=head->next;
}
return true;
}
};
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/intersection-of-two-linked-lists/
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
typedef struct ListNode ListNode;
ListNode* p=headA;//p为工作指针,遍历两个链表并统计长度
int countA=0,countB=0;
while(p!=NULL){//统计headA的长度
p=p->next;
++countA;
}
p=headB;
while(p!=NULL){//统计headB的长度
p=p->next;
++countB;
}
if(countA>countB){
int len=countA-countB;
p=headA;
while(len){//将A链表到相同长度时
p=p->next;
--len;
}
while(p&&headB){//开始进行两链表的比对
if(p==headB){
return p;
}
p=p->next;
headB=headB->next;
}
}else{
int len=countB-countA;
p=headB;
while(len){//将B链表到相同长度时
p=p->next;
--len;
}
while(p&&headA){//开始进行两链表的比对
if(p==headA){
return p;
}
p=p->next;
headA=headA->next;
}
}
return NULL;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-cycle
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。如果链表中存在环 ,则返回 true 。 否则,返回 false 。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
typedef struct ListNode ListNode;
ListNode* fast=head;
ListNode* low=head;
while(fast&&fast->next){//快指针先走,如果是有环那么该循环会永远退不出并最后追上;而fast->next==NULL就是while循环的出口
fast=fast->next->next;
low=low->next;
if(fast==low)
return true;
}
return false;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-cycle-ii
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
typedef struct ListNode ListNode;
ListNode* fast=head;
ListNode* low=head;
while(fast&&fast->next){//判断是否有环
fast=fast->next->next;
low=low->next;
if(low==fast){//有环的话 根据距离公式推算 从当时相遇结点和头节点开始遍历 再次相遇就会是入环结点
ListNode* p=fast;
while(head&&p){
if(head==p){
return p;
}else{
head=head->next;
p=p->next;
}
}
}
}
return NULL;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/copy-list-with-random-pointer
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。
返回复制链表的头节点。
用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
你的代码 只 接受原链表的头节点 head 作为传入参数。
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
struct Node* copyRandomList(struct Node* head) {
typedef struct Node Node;
Node* cur=head;
while(cur){//将结点全部复制一次并链接到该节点后面
Node* copy=(Node*)malloc(sizeof(Node));//创建拷贝的结点
copy->val=cur->val;//将拷贝结点放在当前结点的后面
copy->next=cur->next;
cur->next=copy;
cur=copy->next;
}
cur=head;//工作结点重新修正为原链表的头节点
while(cur){//将节点中的random所指向的值进行复制
if(cur->random==NULL)
cur->next->random=NULL;
else
cur->next->random=cur->random->next;
cur=cur->next->next;
}
Node* copytail,*copyhead=(Node*)malloc(sizeof(Node));//创建拷贝结点链表的头和尾
copyhead=copytail=NULL;
cur=head;//工作结点重新修正为原链表的头节点
while(cur){//将所拷贝的结点链接在一起,原本的结点不改变
Node* next=cur->next->next;//next记录原链表的下一个结点的位置
if(copytail==NULL){//如果拷贝结点最初为空时,
copyhead=copytail=cur->next;
}else{
copytail->next=cur->next;
copytail=copytail->next;
}
cur->next=next;
cur=next;
}
return copyhead;
}
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
typedef char STData;
typedef struct Stack{
int capacity;//栈的容量
int top;//栈顶位置
STData* a;
}Stack;
void StackInit(Stack* s){//栈的初始化
assert(s);
s->a=NULL;
s->capacity=0;
s->top=0;
}
void StackDestroy(Stack* s){//栈销毁
assert(s);
free(s->a);
s->a=NULL;
s->capacity=0;
s->top=0;
}
void StackPush(Stack* s,STData x){//将数据写入栈
assert(s);
if(s->top==s->capacity){
int newCapacity = s->capacity == 0 ? 4 : s->capacity * 2;
s->a=(STData*)realloc(s->a,sizeof(STData)*newCapacity);
if(s->a==NULL){
printf("realloc fail\n");
exit(-1);
}
s->capacity=newCapacity;
}
s->a[s->top]=x;
s->top++;
}
void StackPop(Stack* s){//栈顶元素弹出栈
assert(s);
assert(s->top>0);
--s->top;
}
STData StackTop(Stack* s){//取出栈顶元素
assert(s);
assert(s->top>0);
return s->a[s->top-1];
}
bool StackEmpty(Stack* s){//判断栈是否为空
assert(s);
//printf("%d",s->top);
return s->top==0;
}
bool isValid(char * s){
Stack stack;
StackInit(&stack);
while(*s){
if(*s=='('||*s=='{'||*s=='['){
StackPush(&stack,*s);
++s;
}else{
if(StackEmpty(&stack)){
return false;
}
STData top=StackTop(&stack);
//printf("%d",stack.top);
//printf("%c",top);
// printf("%c\n",*s);
StackPop(&stack);
//printf("%d",stack.top);
if(*s=='}'&&top!='{'
||*s==']'&&top!='['
||*s==')'&&top!='('){
//StackDestroy(&s);
return false;
}else{
++s;
}
}
}
bool ret =StackEmpty(&stack);
StackDestroy(&stack);
return ret;
}
char pairs(char a) {
if (a == '}') return '{';
if (a == ']') return '[';
if (a == ')') return '(';
return 0;
}
bool isValid(char* s) {
int n = strlen(s);
if (n % 2 == 1) {
return false;
}
int stk[n + 1], top = 0;
for (int i = 0; i < n; i++) {
char ch = pairs(s[i]);
if (ch) {
if (top == 0 || stk[top - 1] != ch) {
return false;
}
top--;
} else {
stk[top++] = s[i];
}
}
return top == 0;
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/valid-parentheses/solution/you-xiao-de-gua-hao-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-stack-using-queues/
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
typedef int QDataType;
typedef struct QueueNode //队列结点
{
QDataType data;//结点数据类型
struct QueueNode* next;//结点存储下一个结点的位置
}QNode;
typedef struct Queue//队列
{
QNode* head;
QNode* tail;
}Queue;
typedef struct {
Queue q1;
Queue q2;
} MyStack;
void QueueInit(Queue* pq)//队列初始化
{
assert(pq);
pq->head = pq->tail = NULL;
}
void QueueDestory(Queue* pq)//队列销毁
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x)//进入队列
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
assert(newnode);
newnode->data = x;
newnode->next = NULL;
if (pq->tail == NULL)
{
assert(pq->head == NULL);
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
void QueuePop(Queue* pq)//出队列
{
assert(pq);
assert(pq->head && pq->tail);
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
}
bool QueueEmpty(Queue* pq)//判断队列是否为空
{
assert(pq);
return pq->head == NULL;
}
size_t QueueSize(Queue* pq)//队列的长度
{
assert(pq);
QNode* cur = pq->head;
size_t size = 0;
while (cur)
{
size++;
cur = cur->next;
}
return size;
}
QDataType QueueFront(Queue* pq)//获取队列的第一个元素
{
assert(pq);
assert(pq->head);
return pq->head->data;
}
QDataType QueueBack(Queue* pq)//获取队列的尾元素
{
assert(pq);
assert(pq->tail);
return pq->tail->data;
}
MyStack* myStackCreate() {
MyStack* pst=(MyStack*)malloc(sizeof(MyStack));
assert(pst);
QueueInit(&pst->q1);
QueueInit(&pst->q2);
return pst;
}
void myStackPush(MyStack* obj, int x) {
assert(obj);
if(!QueueEmpty(&obj->q1)){//如果q1不为空那么就为存放数据,反之q2存放数据
QueuePush(&obj->q1,x);
}else{
QueuePush(&obj->q2,x);
}
}
int myStackPop(MyStack* obj) {
assert(obj);
Queue* nonEmptyQ=&obj->q2;//先默认q2为空队列
Queue* emptyQ=&obj->q1;//先默认q1为数据队列
if(!QueueEmpty(&obj->q1)){//判断默认情况是否成立,不成立则交换
emptyQ=&obj->q2;
nonEmptyQ=&obj->q1;
}
while(QueueSize(nonEmptyQ)>1){//队列模拟栈出
int front=QueueFront(nonEmptyQ);
QueuePush(emptyQ,front);//一个队列进
QueuePop(nonEmptyQ);//一个队列出
}
int top=QueueFront(nonEmptyQ);//在最后一个队列进入另一个队列时 返回当前值
QueuePop(nonEmptyQ);
return top;
}
int myStackTop(MyStack* obj) {
assert(obj);
if(!QueueEmpty(&obj->q1)){
return QueueBack(&obj->q1);
}else{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
assert(obj);
return QueueEmpty(&obj->q2)&&QueueEmpty(&obj->q1);
}
void myStackFree(MyStack* obj) {
assert(obj);
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-queue-using-stacks/
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
typedef struct {
int* stk;
int stkSize;
int stkCapacity;
} Stack;
Stack* stackCreate(int cpacity) {
Stack* ret = malloc(sizeof(Stack));
ret->stk = malloc(sizeof(int) * cpacity);
ret->stkSize = 0;
ret->stkCapacity = cpacity;
return ret;
}
void stackPush(Stack* obj, int x) {
obj->stk[obj->stkSize++] = x;
}
void stackPop(Stack* obj) {
obj->stkSize--;
}
int stackTop(Stack* obj) {
return obj->stk[obj->stkSize - 1];
}
bool stackEmpty(Stack* obj) {
return obj->stkSize == 0;
}
void stackFree(Stack* obj) {
free(obj->stk);
}
typedef struct {
Stack* inStack;//一个只进
Stack* outStack;//一个只出
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* ret = malloc(sizeof(MyQueue));
ret->inStack = stackCreate(100);//因为最多操作100次push、pop,所以容量申请为100
ret->outStack = stackCreate(100);//同上
return ret;
}
void in2out(MyQueue* obj) {
while (!stackEmpty(obj->inStack)) {
stackPush(obj->outStack, stackTop(obj->inStack));//一个栈进 一个栈出来模拟队列
stackPop(obj->inStack);//最后将进栈的元素弹出
}
}
void myQueuePush(MyQueue* obj, int x) {
stackPush(obj->inStack, x);
}
int myQueuePop(MyQueue* obj) {
if (stackEmpty(obj->outStack)) {
in2out(obj);
}
int x = stackTop(obj->outStack);
stackPop(obj->outStack);
return x;
}
int myQueuePeek(MyQueue* obj) {
if (stackEmpty(obj->outStack)) {
in2out(obj);
}
return stackTop(obj->outStack);
}
bool myQueueEmpty(MyQueue* obj) {
return stackEmpty(obj->inStack) && stackEmpty(obj->outStack);
}
void myQueueFree(MyQueue* obj) {
stackFree(obj->inStack);
stackFree(obj->outStack);
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/design-circular-queue/
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
typedef struct {
int* a;
int front;//记录队头下标
int tail;//记录队尾下标
int k;//队列长度
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj );
bool myCircularQueueIsFull(MyCircularQueue* obj);
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a=(int*)malloc(sizeof(int)*(k+1));//申请k+1的空间 多一个空间是front和tail的循环
obj->front=obj->tail=0;
obj->k=k;//长度设为k
return obj;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))
return false;
obj->a[obj->tail]=value;
if(obj->tail==obj->k){
obj->tail=0;
}else{
obj->tail++;
}
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))//分两种情况,如果front==k那么就到了队列的最后,再返回就是下标0绕回去
return false;
if(obj->front==obj->k){
obj->front=0;
}else{
obj->front++;
}
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
return obj->a[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
if(obj->tail==0){//考虑到如果tail为0 那么最后一个元素在k位置上
return obj->a[obj->k];
}else{
return obj->a[obj->tail-1];
}
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front==obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
if(obj->tail==obj->k&&obj->front==0){
return true;
}else{
return obj->tail+1==obj->front;
}
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}
https://leetcode.cn/problems/univalued-binary-tree/
如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。
只有给定的树是单值二叉树时,才返回 true;否则返回 false。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool isUnivalTree(struct TreeNode* root){
if(root==NULL)
return true;
if(root->left!=NULL&&root->left->val!=root->val)
return false;
if(root->right!=NULL&&root->right->val!=root->val)
return false;
return isUnivalTree(root->left)&&isUnivalTree(root->right);
}
https://leetcode.cn/problems/binary-tree-preorder-traversal/
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int TreeHeight(struct TreeNode* root){//计算高度
return root==NULL?0:TreeHeight(root->left)+TreeHeight(root->right)+1;
}
void _preorderTraversal(struct TreeNode* root,int *a,int *pi){//先序遍历 将不是NULL值传递给数组
if(root==NULL)
return;
//printf("%d",*pi);
a[(*pi)++]=root->val;
_preorderTraversal(root->left,a,pi);
_preorderTraversal(root->right,a,pi);
return;
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
int size=TreeHeight(root);
//printf("size:%d\n",size);
int *a=(int*)malloc(sizeof(int)*size);
int i=0;
_preorderTraversal(root,a,&i);
*returnSize=size;
return a;
}
https://leetcode.cn/problems/binary-tree-inorder-traversal/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int TreeSize(struct TreeNode* root){
return root==NULL?0:TreeSize(root->right)+TreeSize(root->left)+1;
}
void _inorderTraversal(struct TreeNode* root,int* a,int *pi){
if(root==NULL)
return;
if(root->left!=NULL||root->right!=NULL){
_inorderTraversal(root->left,a,pi);
a[(*pi)++]=root->val;
_inorderTraversal(root->right,a,pi);
return;
}
if(root->left==NULL&&root->left==NULL)
a[(*pi)++]=root->val;
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
typedef struct TreeNode TreeNode;
int size=TreeSize(root);
int i=0;
//printf("%d",size);
int *a=(int*)malloc(sizeof(int)*size);
_inorderTraversal(root,a,&i);
*returnSize=i;
return a;
}
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
https://leetcode.cn/problems/binary-tree-postorder-traversal/
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int TreeSize(struct TreeNode* root){
return root==NULL?0:TreeSize(root->right)+TreeSize(root->left)+1;
}
void _postorderTraversal(struct TreeNode* root,int* a,int *pi){
if(root==NULL)
return;
if(root->left!=NULL||root->right!=NULL){
_postorderTraversal(root->left,a,pi);
_postorderTraversal(root->right,a,pi);
a[(*pi)++]=root->val;
return;
}
if(root->left==NULL&&root->left==NULL)
a[(*pi)++]=root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize){
typedef struct TreeNode TreeNode;
int size=TreeSize(root);
int i=0;
//printf("%d",size);
int *a=(int*)malloc(sizeof(int)*size);
_postorderTraversal(root,a,&i);
*returnSize=i;
return a;
}
https://leetcode.cn/problems/same-tree/
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
if(p==NULL&&q!=NULL)
return false;
if(p!=NULL&&q==NULL)
return false;
if(p==NULL&&q==NULL)
return true;
if(p->val!=q->val)
return false;
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int maxDepth(struct TreeNode* root){
return root==NULL?0:fmax(maxDepth(root->left),maxDepth(root->right))+1;
}
https://leetcode.cn/problems/symmetric-tree/
给你一个二叉树的根节点 root , 检查它是否轴对称。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool _isSymmetric(struct TreeNode* p,struct TreeNode* q){
if(p==NULL&&q==NULL)
return true;
if(p==NULL||q==NULL)
return false;
if(p->val!=q->val)
return false;
return _isSymmetric(p->right,q->left)&&_isSymmetric(p->left,q->right);
}
bool isSymmetric(struct TreeNode* root){
if(root==NULL)
return false;
if(root->right==NULL&&root->left==NULL)
return true;
if(root->right==NULL||root->left==NULL)
return false;
return _isSymmetric(root->right,root->left);
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/subtree-of-another-tree
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool isSameTree(struct TreeNode* p,struct TreeNode* q){
if(p==NULL&&q==NULL)
return true;
if(p==NULL||q==NULL)
return false;
if(p->val!=q->val)
return false;
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
typedef struct TreeNode TreeNode;
if(root==NULL)
return false;
if(isSameTree(root,subRoot))//先比较该节点是否相同
return true;
return isSubtree(root->right,subRoot)||isSubtree(root->left,subRoot);//如果该节点的左右子树有一个能包含子树 那么返回就是true
}
https://leetcode.cn/problems/balanced-binary-tree/
给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int TreeHeight(struct TreeNode* root){
if(root==NULL)
return 0;
int hl=TreeHeight(root->left)+1;
int hr=TreeHeight(root->right)+1;
if(hl>hr)
return hl;
return hr;
}
bool isBalanced(struct TreeNode* root){
if(root==NULL)
return true;
//printf("left:%d right:%d\n",TreeHeight(root->left),TreeHeight(root->right));
if(abs(TreeHeight(root->left)-TreeHeight(root->right))>1)
return false;
return isBalanced(root->left)&&isBalanced(root->right);
}
https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
#include
#include
typedef struct TreeNode{
int val;
struct TreeNode *left;
struct TreeNode *right;
}TreeNode;
TreeNode* CreateTree(char* str,int* pi){
if(str[(*pi)]=='#'){
(*pi)++;
return NULL;
}
TreeNode *root=(TreeNode*)malloc(sizeof(TreeNode));
root->val=str[(*pi)++];
root->left=CreateTree(str,pi);
root->right=CreateTree(str,pi);
return root;
}
void InOrder(TreeNode *root){
if(root==NULL)
return;
InOrder(root->left);
printf("%c ",root->val);
InOrder(root->right);
}
int main() {
char str[100];
int i=0;
while (scanf("%s",str)!=EOF) {
TreeNode *root=CreateTree(str, &i);
InOrder(root);
}
return 0;
}
https://leetcode.cn/problems/invert-binary-tree/
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* invertTree(struct TreeNode* root){
if(root==NULL)
return root;
if(root->left==NULL&&root->right==NULL){
return root;
}
invertTree(root->left);
invertTree(root->right);
struct TreeNode* tmp=root->left;
root->left=root->right;
root->right=tmp;
return root;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/missing-number-lcci/
数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
示例 1:
输入:[3,0,1]
输出:2
示例 2:
输入:[9,6,4,2,3,5,7,0,1]
输出:8
//原理:1^1=0 相同的数字异或会消失 所以原数组异或一次 再创造一组来全部异或一次
int missingNumber(int* nums, int numsSize){
int sum=0;
for(int i=0;i<numsSize;i++){
sum^=nums[i];
}
for(int i=0;i<=numsSize;i++){
sum^=i;
}
return sum;
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* singleNumbers(int* nums, int numsSize, int* returnSize){
int sum=0;
for(int i=0;i<numsSize;i++){
sum^=nums[i];
}
int pos=sum&(-sum);//得到二进制位中的第pos位来分组
int *rs=(int*)calloc(2,sizeof(int));
for(int i=0;i<numsSize;i++){
if(nums[i]&pos)
rs[0]^=nums[i];
else
rs[1]^=nums[i];
}
*returnSize=2;
return rs;
}
描述
找出字符串中第一个只出现一次的字符
数据范围:输入的字符串长度满足
1≤n≤1000
输入描述:
输入一个非空字符串
输出描述:
输出第一个只出现一次的字符,如果不存在输出-1
#include
#include
#include
using namespace std;
int Hash(int key)
{
return key - 'a';
}
int FirstTimeChar(string& str)
{
int hashtable[26] = {0};
//对字符串的每一个字符进行hash映射
for (int i = 0; i < str.size(); ++i)
{
int index = Hash(str[i]);
hashtable[index]++;
}
//按顺序检测每一个字符是否只出现一次
for (int i = 0; i < str.size(); ++i)
{
int index = Hash(str[i]);
if (hashtable[index] == 1)
return str[i];
}
return -1;
}
int main()
{
string str;
while (getline(cin, str))
{
char res = FirstTimeChar(str);
if (res == -1)
cout << -1 << endl;
else
cout << res << endl;
}
return 0;
}
https://www.nowcoder.com/practice/8c949ea5f36f422594b306a2300315da?tpId=37&&tqId=21224&rp=5&ru=/activity/oj&qru=/ta/huawei/question-ranking
描述
计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
输入描述:
输入一行,代表要计算的字符串,非空,长度小于5000。
输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。
#include
using namespace std;
int main() {
string str;
getline(cin,str);
//cout<
int pos=str.find_last_of(" ");
//cout<
str=str.substr(pos+1,str.size());
//cout<
int size=str.size();
cout<<str.size()<<endl;
}
// 64 位输出请用 printf("%lld")
力扣:https://leetcode.cn/problems/first-unique-character-in-a-string/
给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。
class Solution {
public:
int firstUniqChar(string s) {
for(int i=0;i<s.size();i++){
int index=s.find(s[i]);
int reverse_index=s.rfind(s[i]);
if(index==reverse_index)
return i;
}
return -1;
}
};
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reverse-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public:
void reverseString(vector<char>& s) {
//cout<
int left=0,right=s.size()-1;
while(right>left){
char temp=s[left];
s[left]=s[right];
s[right]=temp;
right--;
left++;
}
}
};
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/add-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution
{
public:
//完成每一项的相加,进位可能会被修改,sign以引用传递
int AddItem(int a, int b, int &sign)
{
int sum = a + b + sign;
if(sum >= 10)
{
sum -= 10;
sign = 1;
}
else
sign = 0;
return sum;
}
string addStrings(string num1, string num2)
{
//先逆置数据,方便相加时有进位直接在数据的尾部插入即可,这样不会引起数据的移动
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
int i, j, sign;
i = j = sign = 0;
int sum = 0;
string res;
while(i<num1.size() && j<num2.size())
{
sum = AddItem(num1[i]-'0', num2[j]-'0', sign);
res.push_back(sum+'0');
i++;
j++;
}
while(i < num1.size())
{
sum = AddItem(num1[i]-'0', 0, sign);
res.push_back(sum+'0');
i++;
}
while(j < num2.size())
{
sum = AddItem(0, num2[j]-'0', sign);
res.push_back(sum+'0');
j++;
}
if(sign > 0)
res.push_back(sign+'0');
reverse(res.begin(), res.end());
return res;
}
};
牛客网:https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId=13&&tqId=11202&rp=6&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为 0 或者字符串不是一个合法的数值则返回 0
注意:
①字符串中可能出现任意符号,出现除 +/- 以外符号时直接输出 0
②字符串中可能出现 +/- 且仅可能出现在字符串首位。
class Solution {
public:
int StrToInt(string str)
{
int len = str.size();
int flag = 1;
if (len == 0)
return 0;
const char* cstr = str.c_str();
if (cstr == NULL)
return 0;
int i = 0;
if (cstr[i] == '+')
{
i++;
flag = 1; //如果str[i]为'+',str[i]顺序后移,并令标志flag为1,表示为正数
}
else if (cstr[i] == '-')
{
i++;
flag = -1; //如果str[i]为'-',str[i]顺序后移,并令标志flag为-1,表示为负数
}
long long num = 0;
while (cstr[i] != '\0')
{
if (cstr[i] >= '0' && cstr[i] <= '9')
{
//每遍历一个在0-9间的字符,就将其输入到num中
num = num * 10 + (cstr[i] -
'0'); //下一次输入到num中时要加上上一次*10的结果,即上一次的数左移一位(十进制下)
//如果数据溢出,则返回0
if ((flag > 0 && num > 0x7fffffff) || (flag < 0 && num > 0x80000000))
return 0;
i++;
}
else
{
return 0;
}
}
if (flag < 0)
num = num * -1;
return (int)num;
}
};
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/multiply-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public:
string multiply(string num1, string num2) {
if(num1=="0"||num2=="0")
return "0";
int m=num1.size(),n=num2.size();
auto ansArr = vector<int>(m+n);
for (int i = m - 1; i >= 0; i--) {
int x = num1.at(i) - '0';
for (int j = n - 1; j >= 0; j--) {
int y = num2.at(j) - '0';
ansArr[i + j + 1] += x * y;
}
}
for(int i=m+n-1;i>0;i--){
ansArr[i-1]+=ansArr[i]/10;
ansArr[i]%=10;
}
int index=ansArr[0]==0?1:0;
string ans;
while(index<m+n){
ans.push_back(ansArr[index]);
index++;
}
for(auto &c:ans){
c+='0';
}
return ans;
}
};
力扣:https://leetcode.cn/problems/reverse-words-in-a-string-iii/
给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
class Solution {
public:
void reverse(string &s,int begin,int end){
char temp;
while(begin<end){
temp=s.at(begin);
s[begin]=s[end];
s[end]=temp;
begin++;
end--;
}
}
string reverseWords(string s) {
int begin=0,end=0;
while(s.size()>begin){
end=s.find(' ',begin);//从字符串begin的位置开始搜索空格
//cout<
if(end==string::npos){
end=s.size();
break;
}
reverse(s,begin,end-1);
begin=end+1;
}
reverse(s,begin,end-1);
return s;
}
};
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reverse-string-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public:
void reverse(string &s,int begin,int end){
char temp;
while(begin<end){
temp=s[begin];
s[begin]=s[end];
s[end]=temp;
begin++;
end--;
}
}
string reverseStr(string s, int k) {
for(int i=0;i<s.size();i=i+(2*k)){
if(i+k<s.size()){
reverse(s,i,i+k-1);
continue;
}
reverse(s,i,s.size()-1);
}
return s;
}
};
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-palindrome
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public:
bool isPalindrome(string s) {
string sgood;
for(char ch:s){
if(isalnum(ch)){
sgood+=tolower(ch);
}
}
int begin=0,end=sgood.size()-1;
//cout<
//cout<
while(begin<end){
if(sgood[begin++]!=sgood[end--])
return false;
}
return true;
}
};
https://www.nowcoder.com/practice/eebb2983b7bf40408a1360efb33f9e5d?tpId=40&&tqId=31013&rp=1&ru=/activity/oj&qru=/ta/kaoyan/question-ranking
描述
设计一个程序能计算一个日期加上若干天后是什么日期。
输入描述:
输入第一行表示样例个数m,接下来m行每行四个整数分别表示年月日和累加的天数。
输出描述:
输出m行,每行按yyyy-mm-dd的个数输出。
1
2008 2 3 100
2008-05-13
代码:
#include
using namespace std;
//天数建立数组
int daytab[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
//是否是闰年
bool IsLeapYear(int year){
return (year%4==0&&year%100!=0)||(year%400==0);
}
//判断这一年有多少天
int Numberofyear(int year){
if(IsLeapYear(year))
return 366;
return 365;
}
int main() {
int m,year,month,day,number;
cin>>m;
while (m--) {
while (cin>>year>>month>>day>>number) {
int row=IsLeapYear(year);
for(int i=0;i<month;++i){
number+=daytab[row][i];
}
number+=day;
while (number>Numberofyear(year)) {
number-=Numberofyear(year);
year++;
}
month=0;
row=IsLeapYear(year);
while (number>daytab[row][month]) {
number-=daytab[row][month];
month++;
}
day=number;
//cout<
printf("%04d-%02d-%02d\n",year,month,day);
}
}
}
https://www.nowcoder.com/practice/b1f7a77416194fd3abd63737cdfcf82b?tpId=69&&tqId=29669&rp=1&ru=/activity/oj&qru=/ta/hust-kaoyan/question-ranking
描述
给出年分m和一年中的第n天,算出第n天是几月几号。
输入描述:
输入包括两个整数y(1<=y<=3000),n(1<=n<=366)。
输出描述:
可能有多组测试数据,对于每组数据, 按 yyyy-mm-dd的格式将输入中对应的日期打印出来。
输入:
2000 3
2000 31
2000 40
2000 60
2000 61
2001 60
输出:
2000-01-03
2000-01-31
2000-02-09
2000-02-29
2000-03-01
2001-03-01
#include
using namespace std;
int main() {
int year, day;
int mon[13]={31, 28, 31, 30, 31, 30, 31, 31, 30 ,31, 30, 31};
while (cin >> year >> day) { // 注意 while 处理多个 case
if((year%4==0)&&(year%100!=0)||(year%400==0)){
mon[1]=29;
} else{
mon[1]=28;
}
for(int i=0;i<12;i++){
if(day<mon[i]){
printf("%4d-%02d-%02d\n",year,i+1,day);
break;
}else{
day-=mon[i];
}
}
}
return 0;
}
// 64 位输出请用 printf("%lld")
https://www.nowcoder.com/practice/ccb7383c76fc48d2bbc27a2a6319631c?tpId=62&&tqId=29468&rp=1&ru=
描述
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
输入描述:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出描述:
每组数据输出一行,即日期差值
输入:
20110412
20110422
输出:
11
#include
using namespace std;
int mon[12]={0,31,59,90,120,151,181,212,243,273,304,334};
int CountDay(int year,int month,int day){
int yearDay=year*365+year/4-year/100+year/400;
int monthDay=mon[month-1];
if(month>2&&((year/4==0)&&(year/100!=0)&&(year/400==0)))
monthDay+=1;
return yearDay+monthDay+day;
}
int main() {
int year1, month1, day1;
int year2, month2, day2;
scanf("%4d%2d%2d",&year1,&month1,&day1);
int n1 = CountDay(year1,month1,day1);
scanf("%4d%2d%2d",&year2,&month2,&day2);
int n2 = CountDay(year2,month2,day2);
cout<<abs(n1-n2)+1<<endl;
}
https://www.nowcoder.com/practice/769d45d455fe40b385ba32f97e7bcded?tpId=37&&tqId=21296&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking
描述
根据输入的日期,计算是这一年的第几天。
保证年份为4位数且日期合法。
进阶:时间复杂度:O(n) ,空间复杂度:O(1)
输入描述:
输入一行,每行空格分割,分别是年,月,日
输出描述:
输出是这一年的第几天
输入:
2012 12 31
输出:
366
输入:
1982 3 4
输出:
63
#include
using namespace std;
int main() {
int year,month,day;
cin>>year>>month>>day;
//cout<
int monthDays[13]={0,31,59,90,120,151,181,212,243,273,304,334,365};
int n = monthDays[month-1]+day;
if (month>2&&(((year%4==0)&&(year%100!=0))||year%400==0)){
n+=1;
}
cout<<n<<endl;
return 0;
}
https://www.nowcoder.com/practice/7a0da8fc483247ff8800059e12d7caf1?tpId=13&tqId=11200&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
描述
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
class Solution {
public:
int Sum_Solution(int n) {
if(n==1) return 1;
else
return n+Sum_Solution(n-1);
}
};