刷题是最常见提高coding能力的一种途径,常见的刷题网站有leetcode和牛客等,但是这两者之间有略微的差异,下面对其进行简单的总结:
(1)牛客等ACM模式
什么是ACM输入模式呢? 就是自己构造输入数据格式,把要需要处理的容器填充好,OJ不会给你任何代码,包括include哪些函数都要自己写,最后也要自己控制返回数据的格式。例如,
#include<iostream>
#include<string>
int main(int argc,char ** argv)
{
//核心代码
int n;
while(std::cin>>n)
{
//do it
}
return 0;
}
(2)LeetCode核心代码模式
力扣上是核心代码模式,就是把要处理的数据都已经放入容器里,可以直接写逻辑,比如,
class Solution {
public:
int getDays(vector<int>& work, vector<int>& gym) {
// 处理逻辑
}
};
两种不同风格的编码模式,可以看出ACM模式要比核心代码模式多写不少代码,相对来说ACM模式更锻炼代码能力,而核心代码模式是把侧重点完全放在算法逻辑上。根据自己的需要来进行抉择。
在练习时,经常会碰到需要调试等情况,由于题目输入一般给定的是数组或者列表,当碰到链表,二叉树等题目时,这样就给调试带来一定困难,尤其是leetcode的核心代码模式,这时候需要提前构建好链表或者二叉树的构造类,下面奉上自己常用的代码块(这里给出的是链式存储,至于顺序存储可以自己补充):
- c++版本
1)链表
#include<iostream>
#include<vector>
using namespace std;
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 BuildListNode{
public:
BuildListNode(vector<int>& da){data=da;}
~BuildListNode(){}
ListNode * Build()
{
ListNode * head=new ListNode();
ListNode * tmp=head;
for(int i=0;i<data.size();i++)
{
ListNode * t=new ListNode(data[i]);
tmp->next=t;
tmp=tmp->next;
}
return head->next;
}
private:
vector<int> data;
};
void TraceListNode(ListNode* head)
{
ListNode * tmp = head;
while (tmp) {
cout << tmp->val << endl;
tmp = tmp->next;
}
}
int main()
{
vector<int> tmp={1,2,3};
ListNode * res=BuildListNode(tmp).Build();
TraceListNode(res);
return 0;
}
2)二叉树
需要说明的一点就是输入的数组数据对应的是二叉树的层次遍历结果,对于空节点用NULL表示。
#include<iostream>
#include<vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
TreeNode * BuildTree(vector<int> data,int index)
{
TreeNode * root=nullptr;
if(index < data.size() && data[index]!=NULL)
{
root=new TreeNode(data[index]);
root->left=BuildTree(data,2*index+1);
root->right=BuildTree(data,2*index+2);
}
return root;
}
//先序遍历
void TraceRootFirst(TreeNode * root)
{
if(root==nullptr) return;
cout<<root->val<<endl;
TraceRootFirst(root->left);
TracerootFirst(root->right);
}
int main()
{
vector<int> tmp={1,2,NULL,3,NULL,4};
TreeNode * root=BuildTree(tmp,0);
TraceRootFirst(root);
return 0;
}
- python版本
1)链表
class ListNode:
def __init__(self,val):
self.val=val
self.next=None
def BuildListNode(data):
head=ListNode(0)
tmp=head
for i in data:
tmp.next=ListNode(i)
tmp=tmp.next
return head.next
def TraceListNode(head):
while head:
print(head.val)
head=head.next
if __name__=="__main__":
data=[1,2,3]
res=BuildListNode(data)
TraceListNode(res)
2)二叉树
class ListTree:
def __init__(self,val=0, left=None, right=None):
self.val=val
self.left=left
self.right=right
def BuildListTree(data,index):
root=None
if(index<len(data) and data[index]!=None):
root=ListTree(data[index])
root.left=BuildListTree(data,2*index+1)
root.right=BuildListTree(data,2*index+2)
return root
def TraceListTree(root):
if root==None: return
print(root.val)
TraceListTree(root.left)
TraceListTree(root.right)
if __name__=="__main__":
data=[1,2,3,4,None,None,5]
root=BuildListTree(data,0)
TraceListTree(root)