记录一下,也不知道自己能够坚持多久——2.24
真正开始做这个工作的时间应该是2.22;
希望每天都能肝几道题,哪怕只有一道也好;
深感Xjtu的代码要求太低,总感觉自己这个CS学生没有实感所以开始学习一些基础的算法。
先前的基础:大一学过C——94
大二分流到计算机数据结构——89,面向对象程序设计——99。
但是学校内学习的知识太浅考核也很是水所以我觉得成绩大概没用的吧
自己算是毫无基础的在学习算法,算妥妥的一枚算法萌新,学校背景也不甚突出,还是希望能够把这个板块一直坚持下来吧
如果有幸被XJTU没分流专业或者高中的学弟看到这篇文章,那么希望大家还是尽量避开XJTU的CS吧,XJTU的CS水平其实很一般
不知道其他学校怎么样,反正我们学校在介绍语言课的时候并没介绍关于STL标准库的内容,所以除了在学习算法本身之外,可能也会更新一些关于学习STL的内容。
- 第一道题:相同的树;难度:简单 题号:100
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入: 1 1
/ \ /
2 3 2 3
[1,2,3], [1,2,3]
输出: true
示例 2:
输入: 1 1
/
2 2
[1,2], [1,null,2]
输出: false
示例 3:
输入: 1 1
/ \ /
2 1 1 2
[1,2,1], [1,1,2]
输出: false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/same-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
求解:这道题目相对简单,运用到我们的数据结构中关于二叉树的概念
我简单的采用了一下递归的思想同时也感受到了,递归法对于空间复杂度的一个不友好性。
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p!=NULL&&q!=NULL&&p->val==q->val)
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
else if(p==NULL&&q==NULL)
return true;
else
return false;
}
};
Run result:执行用时:0 ms
内存消耗:12.1 MB(执行空间大概率被A爆了嘻嘻
标解方法很多,但是我感觉我的方法已经不错所以不去看题解了(盲目自信.jpg
2.第二道题:两数相加;难度:中等;题号:2;
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题目我最早看到的时候,觉得很简单,也是数据结构里面的一种结构,链表的应用。最早以为两表长度相等,没仔细看题,白给了两发,后来仔细看了题又有一些东西没考虑,又白给了好几发。而且到最后我的算法都是比较丑陋的。
最后自己A出来的题解:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode * j=l1;
ListNode * q=l2;
int i=0;
int n=0;
while(j!=NULL)
{
j=j->next;
i++;
}while(q!=NULL)
{
q=q->next;
n++;
}
ListNode *p;
ListNode *m;
if(i>=n)
{p=l1;
m=l2;}
else
{p=l2;
m=l1;}//p是较长的链的指针;
while(p!=NULL)
{
if(p!=NULL&&m!=NULL)
{p->val=p->val+m->val;
m=m->next;
if(p->val>=10)
{p->val=p->val%10;
if(m!=NULL)
m->val=m->val+1;
else
{
if(p->next==NULL)
{p->next=new ListNode(0);
p->next->val=1;
}
else{m=new ListNode(1);
m->val=1;}
}
}
p=p->next;}
else{
p=p->next;
}
}
if(i>=n)
return l1;
else
return l2;
}
};
大致的一个思路的话就是,把两个链中较长的一个转存为p,较短的那个转存为m
那么我们最终只要对p上的val进行操作就可以得到相对固定的值,并且新增节点的个数也相对的少,由于是较长的链,我们知道相加的程度里有几个特殊情况,比如进位的情况,如果之后还有几位更大的,那么我们直接在后面的位数里加一,如果后面没有了,那么就需要扩展我们的链表长度然后直接给最后一位赋值为一。
题解中给的另外一个解法就是把两个链表的长度补成一样的,就短链最后的部分完全补成长链如果没补完就赋值为零
就比如
【1,2,3,5,7】——》【1,2,3,5,7】
【1】 【1,0,0,0,0】
相对要考虑的情况就少一种
代码也贴一下
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head=new ListNode(-1);//存放结果的链表
ListNode* h=head;//移动指针
int sum=0;//每个位的加和结果
bool carry=false;//进位标志
while(l1!=NULL||l2!=NULL)
{
sum=0;
if(l1!=NULL)
{
sum+=l1->val;
l1=l1->next;
}
if(l2!=NULL)
{
sum+=l2->val;
l2=l2->next;
}
if(carry)
sum++;
h->next=new ListNode(sum%10);
h=h->next;
carry=sum>=10?true:false;
}
if(carry)
{
h->next=new ListNode(1);
}
return head->next;
}
作者:chenlele
链接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-gpe3dbjds1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
最初的一次blog只有两道题目,自己却也花了不少时间
A第一题相对较快10min以内,第二道就连续出错。
再加上写题解,不说了,去上编译原理了Orz