区间和(第九期模拟笔试)
错误描述:
代码存在潜在的数组越界问题。
#include<iostream>
#include<vector>
using namespace std;
void sum()
{
int n=0,sum=0;
cin >> n;
int *array=new int[n];
for (int i = 0; i < n; i++)
{
cin >> array[i];
}
int left =0, right = 0;
while (true)
{
cin >> left;
cin >> right;
if (left < 0 || right >= n)
{
break;
}
else {
for (int i = left; i <= right; i++)
{
sum += array[i];
}
cout << sum << endl;
sum = 0;
}
}
delete []array;
array = nullptr;
}
int main() {
sum();
}
欢迎指正
欢迎各位帮忙找出错误,谢谢大家。
设计链表
题目描述
C++代码
class MyLinkedList {
public:
// 定义链表节点结构体
struct LinkedNode {
int val;
LinkedNode* next;
LinkedNode(int val):val(val), next(nullptr){}
};
// 初始化链表
MyLinkedList() {
_dummyHead = new LinkedNode(0); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
_size = 0;
}
// 获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第0个节点就是头结点
int get(int index) {
if (index > (_size - 1) || index < 0) {
return -1;
}
LinkedNode* cur = _dummyHead->next;
while(index--){ // 如果--index 就会陷入死循环
cur = cur->next;
}
return cur->val;
}
// 在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头结点
void addAtHead(int val) {
LinkedNode* newNode = new LinkedNode(val);
newNode->next = _dummyHead->next;
_dummyHead->next = newNode;
_size++;
}
// 在链表最后面添加一个节点
void addAtTail(int val) {
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(cur->next != nullptr){
cur = cur->next;
}
cur->next = newNode;
_size++;
}
// 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
// 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
// 如果index大于链表的长度,则返回空
// 如果index小于0,则在头部插入节点
void addAtIndex(int index, int val) {
if(index > _size) return;
if(index < 0) index = 0;
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(index--) {
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
_size++;
}
// 删除第index个节点,如果index 大于等于链表的长度,直接return,注意index是从0开始的
void deleteAtIndex(int index) {
if (index >= _size || index < 0) {
return;
}
LinkedNode* cur = _dummyHead;
while(index--) {
cur = cur ->next;
}
LinkedNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
//delete命令指示释放了tmp指针原本所指的那部分内存,
//被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
//如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针
//如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
tmp=nullptr;
_size--;
}
// 打印链表
void printLinkedList() {
LinkedNode* cur = _dummyHead;
while (cur->next != nullptr) {
cout << cur->next->val << " ";
cur = cur->next;
}
cout << endl;
}
private:
int _size;
LinkedNode* _dummyHead;
};
删除链表的倒数第N个结点
题目描述
错误描述
拿到这道题的时候,由于没有掌握指针的基础概念而导致书写的时候出现错误,以为只要是将地址赋值给了指针,当操作指针的时候就会改变原来指向空间的值,其实必须要是解引用的状态进行修改才可以。在理解清楚之后书写的代码如下:
代码一:
直接找到要删除结点的前一个结点,然后执行删除操作,不过需要考虑空指针的情况——当结点只有一个的时候需要单独进行处理。
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* virtualHead = new ListNode(0);
virtualHead->next = head;
ListNode* virtualHeadOne = new ListNode(0);
virtualHeadOne->next = head;
ListNode* cur = virtualHeadOne;
//统计一共有多少个结点
int num = 0;
while (virtualHead!=NULL)
{
virtualHead = virtualHead->next;
num++;
}
//删除结点,要处理空指针
if (num>2)
{
for (int i = 1; i < num - n; i++)
{
cur = cur->next;
}
//处理空指针的情况
cur->next = cur->next->next;
}
else {
cur->next = NULL;
}
return virtualHeadOne->next;
}
代码二:
采用双指针的写法。一个快指针和一个慢指针,先让快指针移动n位,然后开始移动慢指针,直至快指针移动到链表尾。这时慢指针就刚好移动到了要删除的结点处,但是这里是要找到删除结点的前一个结点,因此需要将移动的位数加一。
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* virtualHead = new ListNode(0);
ListNode* slow, * fast;
virtualHead->next = head;
slow = virtualHead;
fast = virtualHead;
n++;
for (int i = 0; i < n; i++)
{
fast = fast->next;
}
while (fast != NULL)
{
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return virtualHead->next;
}
环形链表
题目描述:
题目分析:
这个题目最基本的是要弄清楚数学逻辑:
代码:
ListNode *detectCycle(ListNode *head) {
ListNode* slow, * fast,*indexOne=NULL,*indexTwo=NULL;
slow = head;
fast = head;
while (fast!=NULL&&fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
indexOne = head;
indexTwo = fast;
while (indexOne != indexTwo)
{
indexOne = indexOne->next;
indexTwo = indexTwo->next;
}
break;
}
}
return indexOne;
}
哈希表理论基础
容器unordered_set:
set.find(sum)
:这个方法尝试在集合中查找值为 sum
的元素。如果找到了,它返回一个指向该元素的迭代器;如果没有找到,它返回一个特殊的迭代器,即 set.end()
字符串
题目描述:
思路为先去掉多余的空格,之后在将整个字符串反转,之后再将字符串里面的每一个单词进行反转。
去掉多余空格操作:
//去除空格
int slow = 0;
int fast = 0;
//在原有的字符串上直接进行改变
for (; fast < s.size(); fast++)
{
if (s[fast] != ' ')
{
if (slow != 0) {
s[slow++] = ' ';
}
while (fast<s.size()&&s[fast]!=' ')
{
s[slow++] = s[fast++];
}
}
}
s.resize(slow);
这段代码为在原来的字符串上直接进行操作,根据空格这个条件。
代码:
string reverseWords(string s) {
//去除空格
int slow = 0;
int fast = 0;
//在原有的字符串上直接进行改变
for (; fast < s.size(); fast++)
{
if (s[fast] != ' ')
{
if (slow != 0) {
s[slow++] = ' ';
}
while (fast<s.size()&&s[fast]!=' ')
{
s[slow++] = s[fast++];
}
}
}
s.resize(slow);
//将这个字符串反转
int i = 0, j = s.size() - 1;
while (i < j)
{
char temp = s[i];
s[i] = s[j];
s[j] = temp;
i++;
j--;
}
//将字符串中的每一个单词反转
int a = 0, b = 0;
for (; b < s.size(); b++)
{
if (s[b] == ' ')
{
int slow = a,fast=b-1;
while (slow < fast)
{
char temp = s[slow];
s[slow] = s[fast];
s[fast] = temp;
slow++;
fast--;
}
a = b + 1;
}
else if (b == s.size() - 1)
{
int slow = a, fast = b;
while (slow < fast)
{
char temp = s[slow];
s[slow] = s[fast];
s[fast] = temp;
slow++;
fast--;
}
}
}
return s;
}
栈:
删除字符串中的所有相邻重复项:
题目描述:
代码:
stack<char>myStack;
for (int i = 0; i < s.size(); i++)
{
if (myStack.empty()||s[i] != myStack.top())
{
myStack.push(s[i]);
}
else {
myStack.pop();
}
}
string result="";
while (!myStack.empty())
{
result += myStack.top();
myStack.pop();
}
int i = 0, j = result.size() - 1;
while (i < j)
{
char temp = result[i];
result[i] = result[j];
result[j] = temp;
i++;
j--;
}
return result;
}
错误代码:
string removeDuplicates(string s) {
stack<char>myStack;
for (int i = 0; i < s.size(); i++)
{
if (myStack.empty()||s[i] != myStack.top())
{
myStack.push(s[i]);
}
else {
myStack.pop();
}
}
string result="";
for (int i = 0; i < myStack.size(); i++)
{
result += myStack.top();
myStack.pop();
}
int i = 0, j = result.size() - 1;
while (i < j)
{
char temp = result[i];
result[i] = result[j];
result[j] = temp;
i++;
j--;
}
return result;
}
这里在将栈中的元素变成字符串的时候出现了错误,因为栈的大小随着pop操作而变化。
string result="";
for (int i = 0; i < myStack.size(); i++)
{
result += myStack.top();
myStack.pop();
}