#include<vector>
#include<limits>
// 包含INT_MAX, INT_MIN,FLT_MAX, FLT_MIN 等定义
#include<algorithm> → min() max()
//int new_i= min(m-1, i+k/2-1);
//int new_j= min(n-1, j+k/2-1);
#include <string>
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int n= nums.size()-1;
quicksort(nums, 0, n);
return nums;
}
//快排
void quicksort(vector<int>& nums,int left, int right ){
if(left>right){
return;
}
int i,j,temp;
i= left;
j= right;
temp= nums[left];
while(i!=j){
while(nums[j]>=temp && i<j){
j--;
}
while(nums[i]<=temp && i<j){
i++;
}
if(i<j){
int t;
t= nums[i];
nums[i]= nums[j];
nums[j]= t;
}
}
nums[left]= nums[i];
nums[i]= temp;
quicksort(nums,left,i-1);
quicksort(nums,i+1,right);
}
};
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int n= nums.size()-1;
quicksort(nums, 0, n);
return nums;
}
//快排(优化)
void quicksort(vector<int>& nums,int left, int right ){
if(left>right){
return;
}
int i,j,temp;
i= left;
j= right;
//随机枢轴
int ra= left+ rand()%(right-left+1);
swap(nums[left],nums[ra]);
temp= nums[left];
while(i!=j){
while(nums[j]>=temp && i<j){
j--;
}
while(nums[i]<=temp && i<j){
i++;
}
if(i<j){
swap(nums[i],nums[j]);
}
}
swap(nums[left],nums[i]);
quicksort(nums,left,i-1);
quicksort(nums,i+1,right);
}
};
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int n= nums.size()-1;
quicksort(nums, 0, n);
return nums;
}
//快排(再优化)
void quicksort(vector<int>& nums,int left, int right ){
if(left>right){
return;
}
int i,j,temp;
i= left;
j= right;
//随机枢轴
int ra= left+ rand()%(right-left+1);
swap(nums[left],nums[ra]);
temp= nums[left];
while(i!=j){
while(nums[j]>=temp && i<j){
j--;
}
nums[i]= nums[j];
while(nums[i]<=temp && i<j){
i++;
}
nums[j]= nums[i];
}
nums[i]= temp;
quicksort(nums,left,i-1);
quicksort(nums,i+1,right);
}
};
#include<limits>
// 包含INT_MAX, INT_MIN,FLT_MAX, FLT_MIN 等定义
class Solution {
public:
int reverse(int x) {
int num= 0;
while(x!= 0){
if(num> INT_MAX/10 || num< INT_MIN/10)return 0;
//提前判溢
num= num*10+ x%10;
x= x/10;
}
return num;
}
};
class Solution {
public:
int findGCD(vector<int>& nums) {
//int min= nums[0], max= nums[0];
int min= INT_MAX, max= INT_MIN;
//for(int num : nums) 用于遍历容器 nums 中的每个元素
//for(int i= 0; i<sizeof(nums)/sizeof(nums[0]); i++)如果nums为空,访问其元素会报错
for(int num: nums){
if(num>max) max= num;
if(num<min) min= num;
}
return gcd(max,min);
}
//辗转相除
int gcd(int m, int n){
while(m%n!= 0){
int r= m%n;
m= n;
n= r;
}
return n;
}
/*
int gcd(int m, int n){
if(m%n==0)return n;
else return gcd(n, m%n);
}
*/
};
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
//求数组长度 .size()
int n= digits.size();
if(digits[n-1]!= 9){
digits[n-1] +=1;
return digits;
}
int sum= 0;
for(int num: digits) sum= sum*10+num;
sum +=1;
//#inculde<cmath> = pow(double base, double exponent) 平方项(double型)
//#inculde<cmath> = sqrt() 开根号
//#include<cmath> =log() 以e为底 =log10() 以10为底 =log()/log(m) 以m为底
if(sum/int(pow(10,n))== 0){
for(int i= n-1 ; i>-1; i--){
digits[i]= sum%10;
sum= sum/10;
}
return digits;
}
//int arr[9]; //静态数组,不允许改变,定义时得是常数,如9
//#include<vector>
//vector 动态数组,它允许你在运行时动态地插入和删除元素
//vector<int> v2(10, 0); //构造含有10个0的int型容器
//vector<int> v3(v2); //拷贝构造int类的v2容器的复制品
//v.insert(v.end(), 2, 6);//在最后一个位置插入2个 6
//v.insert(v.begin(), 3);// 在第一个元素前插入3
//v.insert(v.begin(), v1.begin(), v1.end());//从v头开始,连续插入v1区间[begin, end]的所有元素
//v.emplace(arr.begin(), 10);//在容器中只加一个元素
//v.emplace_back(1);//在容器中末尾只加一个元素
//v.erase(v.begin());// 删除指定位置的元素
//v.erase(v.begin(), v.begin() + 2);// 删除指定区间的元素
vector<int> vec(n+1);
for(int i= 0; i<n+1; i++){
vec[n-i]= sum%10;
sum= sum/10;
}
return vec;
//在子函数中,定义的数组变量是不允许返回的
}
};
我艹艹艹,溢出了
修改
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int n= digits.size();
int flag= 0;
digits[n-1]= digits[n-1]+1;
for(int i= n-1; i>-1; i--){
if(digits[i]==10){
digits[i]= 0;
if(i!=0)digits[i-1]= digits[i-1]+1;
else flag= 1;
}
}
if(flag==0)return digits;
vector<int> v(n+1,0);
v[0]= 1;
return v;
}
};
class Solution {
public:
int countPrimes(int n) {
//1既非质数(素数)也非合数
if(n==0 || n== 1)return 0;
else if(n==2 || n==3 )return n-2;
else{
int count= 2;
for(int i=4; i<n; i++){
int flag= 0;
for(int j=2; j*j<=i; j++){
//continue:跳出当前循环,即不执行continue后的语句,直接进入下次循环
//break:跳出for循环本身
if(i%j==0){
flag= 1;
break;
}
}
if(flag== 0)count++;
}
return count;
}
}
};
枚举没有考虑到数与数的关联性,因此难以再继续优化时间复杂度。
方法二:埃氏筛
class Solution {
public:
int countPrimes(int n) {
vector<int> isPrim(n,1);
int count= 0;
for(int i= 2; i<n; i++){
if(isPrim[i]==1){
count+= 1;
if(i< n){
for(int j= i; j<n; j+= i){
isPrim[j]= 0;
}
}
}
}
return count;
}
};
class Solution {
public:
string addBinary(string a, string b) {
int al= a.size();
int bl= b.size();
//"aacb"= "aa"+"cb" //字符串拼接
while(al<bl){
a= '0'+a;
al++;
}
while(bl<al){
b= '0'+b;
bl++;
}
//st= "adfg"; → st[0]= a;
//'B'= 'A'+1; //字符串加减
int carry_flag= 0; //进位符号carry_flag
for(int i= al-1; i>=0; i--){
int dt= a[i]-'0'+ b[i]-'0' +carry_flag; //增量dt
a[i]= dt%2+'0';
carry_flag= dt/2;
}
if(carry_flag!= 0){
a= '1'+a;
}
return a;
}
};
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int count= 0;
for(int i= 0; i<nums.size(); i++){
if(nums[i]!=val)count++;
}
//区间划分,双指针
int di= -1;
for(int j= 0; j<nums.size(); j++){
if(nums[j]!=val){
di++;
if(di!=j){
swap(nums[di],nums[j]);
}
}
}
return count;
}
};
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
//非严格递增:一个序列中的元素从小到大排列,但是可以有相同的元素
//写法1 区间划分
/*
int di= 0;
for(int j= 1; j<nums.size();j++){
if(nums[j]!=nums[j-1]){
di++;
nums[di]= nums[j];
}
}
return di+1;
*/
//写法2 快慢指针
int fast= 1, slow= 0;
while(fast<nums.size()){
if(nums[fast]!=nums[fast-1]){
slow++;
nums[slow]= nums[fast];
}
fast++;
}
return slow+1;
}
};
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size()<=2){
return nums.size();
}
int fast= 2, slow= 2;
while(fast<nums.size()){
//nums[slow]=nums[fast]的条件,nums[fast]与有序序列前k位不同
if(nums[fast]!=nums[slow-2]){
nums[slow]= nums[fast];
slow++;
}
fast++;
}
return slow++;
}
};
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//法1:双指针i,j
//将nums2插入nums1,遍历nums2,下标j
//nums1中找到第一个大于等于nums2的或超出nums1有序序列边界的,下标i
//后移1位
//nums1[i]= nums2[j]
/*
int i= 0;
for(int j= 0; j<n; j++){
while(nums1[i]<nums2[j] && i<m+j){
i++;
}
for(int k= m+n-1; k>i; k--){
nums1[k]= nums1[k-1];
}
nums1[i]= nums2[j];
*/
//法2:辅助数组(空间换时间),双指针
vector<int> v(nums1);
int i= 0, j= 0;
while(i+j<m+n){
if(n==0)break;
//注:写成if(v[i]<=nums2[j] && i<m) || j==n) 可能会堆缓冲区溢出heap-buffer-overflow
if(j==n || (v[i]<=nums2[j] && i<m)){
nums1[i+j]= v[i];
i++;
}else{
nums1[i+j]= nums2[j];
j++;
}
}
}
};
4. 寻找两个正序数组的中位数 (二分查找,递归,数学) 难
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int Len= nums1.size()+nums2.size();
if(Len%2==1)return GetMid(nums1,nums2,Len/2+1,0,0);
else return (GetMid(nums1,nums2,Len/2,0,0)+GetMid(nums1,nums2,Len/2+1,0,0))/2;
}
//找两个有序数组A,B中的第k小的数,i,j分别为数组下标(索引)
//法1:俩下标针遍历,时间复杂度O(m+n);
//法2:二分查找,时间复杂度O(log(m+n));
/*
比较A[k/2−1]和B[k/2−1]
由于A[k/2−1]和B[k/2−1]前面分别有k/2−1个元素
对于A[k/2−1]和B[k/2−1]中的较小值,最多只会有(k/2−1)+(k/2−1)≤k−2个元素比它小
那么它就不能是第k小的数了
*/
double GetMid(vector<int>& v1, vector<int>& v2, int k, int i, int j){
int m= v1.size();
int n= v2.size();
if(i==m)return v2[j+k-1];
else if(j==n)return v1[i+k-1];
else if(k==1)return min(v1[i],v2[j]);
//#include<algorithm> → min() max()
int new_i= min(m-1, i+k/2-1);
int new_j= min(n-1, j+k/2-1);
if(v1[new_i]<v2[new_j]){
k= k-(new_i-i+1);
i= new_i+1;
return GetMid(v1, v2, k, i, j);
}else{
k= k-(new_j-j+1);
j= new_j+1;
return GetMid(v1, v2, k, i, j);
}
}
};
/**
* struct ListNode {
* int val;
* ListNode *next;
// 默认构造函数,初始化节点值为0,指针为nullptr(空指针)
* ListNode(): val(0), next(nullptr){}
// 构造函数,使用一个整数初始化节点值,指针默认为nullptr
* ListNode(int x): val(x), next(nullptr){}
// 构造函数,使用一个整数初始化节点值,同时设置指向下一个节点的指针
* ListNode(int x, ListNode *next): val(x), next(next){}
* };
// 创建单个节点
ListNode* node1 = new ListNode(1); // val = 1, next = nullptr
*/
class Solution {
public:
vector<int> v;
// Solution类的构造函数,用于初始化一个Solution对象
Solution(ListNode* head) {
while(head!= NULL){
v.emplace(v.end(),head->val);
head= head->next;
}
}
int getRandom() {
//#include <stdlib.h> → rand()
return v[rand()%v.size()];
}
};
/**
//创建一个Solution类的对象 obj,并将其分配在堆内存上
* Solution *obj= new Solution(head);
* int param_1= obj->getRandom();
*/
/**
* 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* removeElements(ListNode* head, int val) {
//题目不带头节点(哑节点),故先建一个头节点
ListNode* real_head= new ListNode(0,head);
ListNode *pre= real_head, *p= pre->next;
while(p){
if(p->val==val){
pre->next= p->next;
//使用delete来释放通过new分配的内存
delete(p);
p= pre->next;
}else{
pre= pre->next;
p= pre->next;
}
}
return real_head->next;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
ListNode* p_pre= node;
ListNode* p= node->next;
while(p->next!=NULL){
p_pre->val= p->val;
p_pre= p_pre->next;
p= p->next;
}
p_pre->val= p->val;
p_pre->next= NULL;
}
};
/**
* 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* reverseList(ListNode* head) {
if(head==NULL)return head;
//new一个结构体
ListNode* L= new ListNode();
//头插法
ListNode* r;
while(head!=NULL){
r= head->next;
head->next= L->next;
L->next= head;
head= r;
}
L= L->next;
return L;
}
};
/**
* 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* reverseBetween(ListNode* head, int left, int right) {
ListNode* h= new ListNode();
h->next= head;
ListNode* p= h;
for(int i= 0; i<left-1; i++){
p= p->next;
}
ListNode* r;
ListNode* q= p->next;
ListNode* first_q= q;
for(int i= left; i<=right; i++){
r= q->next;
if(q==first_q)q->next= NULL;
else q->next= p->next;
p->next= q;
q= r;
}
first_q->next= q;
head= h->next;
return head;
}
};
class CustomStack {
public:
vector<int> data;
int top;
//b.resize(a,0):改变容器的大小,且创建对象
CustomStack(int maxSize) {
data.resize(maxSize);
top= -1;
}
void push(int x) {
//stk.size()为无符号整型,改为(int)stk.size()
if(top<(int)data.size()-1){
top++;
data[top]= x;
}
}
int pop() {
if(top!=-1){
top--;
return data[top+1];
}else{
return -1;
}
}
void increment(int k, int val) {
for(int i= 0; i<=top && i<k; i++){
data[i]= data[i]+val;
}
}
};
/**
* Your CustomStack object will be instantiated and called as such:
* CustomStack* obj = new CustomStack(maxSize);
* obj->push(x);
* int param_2 = obj->pop();
* obj->increment(k,val);
*/
假设表达式中允许包含圆括号、方括号和大括号3种括号(有优先级),编写一个算法判断表达式中的括号是否正确配对。
(链栈的结构体、一般操作定义)
typedef struct linknode{
char data;
struct linknode *next;
}LinkStack;
void InitStack(LinkStack *&st){
st= (LinkStack*)malloc(sizeof(LinkStack));
st->next= NULL;
}
bool Push(LinkStck *&st, char e){
LinStack *p;
p= (LinkStack*)malloc(sizeof(LinkStack));
p->data= e;
p->next= st->next;
st->next= p;
return true;
}
bool Pop(LinkStack *&st, char &e){
if(st->next==NULL)return false;
LinkStack *p;
p= st->next;
e= p->data;
st->next= p->next;
free(p);
return true;
}
bool GetTop(LinkStack *st, char &e){
if(st->next==NULL)return false;
e= st->next->data;
return true;
}
bool StackEmpty(LinkStack *st){
if(st->next==NULL)return true;
else return false;
}
void DestroyStack(LinkStack *&st){
LinkStack *p_pre=st, *p=p_pre->next;
while(p!=NULL){
free(p_pre);
p_pre= p;
p= p->next;
}
free(p);
}
bool IsMatch(char a[], int n) {
LinkStack *st;
InitStack(st);
int e;
for(int i= 0; i<n; i++){
switch(a[i]){
case '(':
Push(st,a[i]);
break;
case '[':
Push(st,a[i]);
break;
case '{':
Push(st,a[i]);
break;
case ')':
if (Pop(st,e)==true && e!= '(') return false;
break;
case ']':
if (Pop(st,e)==true && e!= '[') return false;
break;
case '}':
if (Pop(st,e)==true && e!= '{') return false;
break;
default:
break;
}
}
if (IsEmpty(st)==true)
return true;
else return false;
}
设从键盘输入一个序列的字符a_1, a_2, ... , a_n。设计一个算法实现这样的功能:
若a_i为数字字符,a_i进队;若a_i为小写字母,将队首元素出队;
若a_i为其他字符,表示输入结束。
要求使用环形队列
# define MaxSize 50
typedef struct{
int data[MaxSize];
int front,rear;
}SqQueue;
void InitQueue(SqQueue *&qu){
qu= (SqQueue*)malloc(sizeof(SqQueue));
qu->front= qu->rear= 0;
}
bool enQueue(SqQueue *&qu, int e){
if((qu->rear+1)%MaxSize==qu->front)return false;
else{
qu->rear= (qu->rear+1)%MaxSize;
qu->data[q->rear]= e;
return true;
}
}
bool deQueue(SqQueue *&qu, int &e){
if(qu->rear==qu->front)return false;
else{
qu->front= (qu->front+1)%MaxSize;
e= qu->data[qu->front];
return true;
}
}
bool QueueEmpty(SqQueue *qu){
if(qu->front=qu->rear)return true;
else return false;
}
int QueueCount(SqQueue *qu){
return (qu->rear-qu->front+MaxSize)%MaxSize;
}
void DestroyQueue(SqQueue *&qu){
free(qu);
}
void processInput(){
SqQueue *qu;
qu= InitQueue(qu);
char input;
while(true){
scanf('%c', &input)
//isdigit是C++用于判断一个字符是否是数字字符('0' 到 '9')的函数 --#include <cctype>
if(isdigit(input)){
if(enQueue(qu, input))print("%c入队", input);
}
else if(islower(input)){
char out;
if(deQueue(qu, &out))print("%c出队",out)
}else break;
}
}
int main() {
processInput();
printf("over");
return 0;
}
KMP算法(匹配模式串) 看看
//模式串t的next数组
//j 序号,t[j] 元素,next[j]=k 记录t[j]之前与t开头相同字符的个数
//无论是否加&,在函数中修改数组的值都可以传递回去
void GetNext(char t[], vector<int> next){
t_size= sizeof(t)/sizeof(t[0]);
int j,k;
j= 0; k=-1;
next[0]= -1;
//next[j+1]根据t[j]是否可纳入t[0]~t[k]得出
while(j<t_size-1){
if(k==-1 || t[k]==t[j]){
j++; k++;
next[j]= k;
}else k= next[k];
//k的回退
}
}
int KMPIndex(char s[], char t[]){
//#include <vector>
vector<int> next(t.size());
GetNext(t,next);
s_size= sizeof(s)/sizeof(s[0]);
t_size= sizeof(t)/sizeof(t[0]);
int i,j;
i= 0; j= 0;
while(i<s_size && j<t_size){
if(j==-1 || s.data[i]==t.data[j]){
i++; j++;
}else j= next[j];
}
if(j==t__size)return(i-t_seze);
else return -1;
}
/*
1、sizeof():返回静态数组所占总空间的字节数
(1)、对于整型字符型数组
(2)、对于整型或字符型指针
2、 .size():返回vector或stringh或array容器元素个数
3、strlen():返回char a[]的长度 #include <cstring>
*/
//模式串t的nextval数组
void GetNextval(char t[], vector<int> nextval){
//#include <cstring>
//strlen()求char a[]字符个数
t_size= strlen(t);
int j,k;
j=0; k=-1;
nextval[0]= -1;
while(j<t_size-1){
if(k==-1 || t[j]==t[k]){
j++; k++;
if(t[j]==t[k])nextval[j]= nextval[k];
else nextval[j]= k;
}else k= nextval[k];
}
}
学习递归
n A B C
将A的n环借助B移动到C
递归终止条件: A只有一环,则将该环直接移动到C
将A的前n-1环借助C移动到B
将A的第n环移动到C
将B的n-1环借助A移动到C
class Solution {
public:
void hanota(vector<int>& A, vector<int>& B, vector<int>& C){
int n= A.size();
Hanoi(n,A,B,C);
}
void Hanoi(int n, vector<int>& A, vector<int>& B, vector<int>& C){
if(n==1){
move(A,C);
return;
}
Hanoi(n-1,A,C,B);
move(A,C);
Hanoi(n-1,B,A,C);
}
void move(vector<int>& A, vector<int>& C){
//写法1
C.push_back(A.back());
A.pop_back();
//写法2
//C.insert(C.end(),A.back());
//A.erase(A.end()-1);
}
//A.back() 返回的是容器最后一个元素的值
//A.front() 返回的是容器第一个元素的值
//对vector容器进行栈操作 A.push_back(Element), A.pop_back()
//对于vector<int> 类型的容器,你只能使用push_back(),而不能直接使用push_front()
//进行A.insert(),A.erase()时,只能对容器进行操作
//A.end() 是一个迭代器,返回一个指向容器最后一个元素的下一个位置
// 若需要最后一个元素的迭代器,用A.end()-1
//A.begin() 是一个迭代器,返回一个指向容器第一个元素的迭代器
};
已知A[0..n-1]为实数数组,设计一个递归算法求这n个元素的平均值。
double average(int A[], int n){
//递归出口
if(n==1)return A[0];
//递归主体
return (A[n-1]+average(A, n-1)*(n-1))/n
}
上楼可以一步上一个台阶,也可以一步上两阶,设计一个递归算法,计算共有多少种不同的走法。
斐波那契数列问题
递归公式可以表示为: f(n)=f(n−1)+f(n−2)
int fun(int step_nums) {
if (step_nums<=0) return 0;
if (step_nums==1) return 1;
if (step_nums==2) return 2;
return fun(step - 2) + fun(step - 1);
}
设有一个不带表头结点的单链表L ,设计两个递归算法,traverse(L)正向输出单链表L中的所有结点值,traverseR(L)反向输出单链表L中的所有结点值。
typedef struct LNode{
int data;
struct LNode *next;
}LinkList;
void traverse(LinkList* L) {
if(L==NULL) return;
printf('%d\t',L->data);
traverse(L->next);
}
void traverseR(LinkList* L) {
if (L==NULL) return;
traverse(L->next);
printf('%d\t',L->data);
}
设有一个不带表头结点的单链表L,设计两个递归算法,del(L, x)删除单链表L中第一个值为x的结点, delall(L, x)删除单链表L中所有值为x的结点。
typedef struct LNode{
int data;
struct LNode *next;
}LinkList;
void del(LinkList* L, int x) {
if (L==NULL) return;
if (L->data==x) {
if(L->next!==NULL){
L->data= L->next->data;
L->next= L->next->next;
}else L= NULL;
return;
}
del(L->next, x);
}
void delall(LinkList* L, int x) {
if (L==NULL) return;
delall(L->next, x);
if (L->data==x) {
if(L->next!==NULL){
L->data= L->next->data;
L->next= L->next->next;
}else L= NULL;
return;
}
}
设有一个不带表头结点的单链表L,设计两个递归算法,maxnode(L)返回单链表L中的最大结点值, minnode(L)返回单链表 L中的最小结点值。
int maxnode(LinkList* L){
if (L==NULL) return;
if (L->next==NULL)return L->data;
int max= maxnode(L->next);
if(max>L->data)return max;
else return L->data;
}
int minode(LinkList* L){
if (L==NULL) return;
if (L->next==NULL)return L->data;
int min= minode(L->next);
if(min<L->data)return min;
else return L->data;
}
/**
* 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:
bool isPalindrome(ListNode* head) {
//ListNode *L;
//L= (ListNode*)malloc(sizeof(ListNode))
ListNode* L= new ListNode();
ListNode* h= head;
while(h!=NULL){
ListNode* t= new ListNode(h->val);
t->next= L->next;
L->next= t;
h= h->next;
}
h= head;
while(h!=NULL){
if(h->val!=L->next->val)return false;
h= h->next;
L= L->next;
}
return true;
}
};
class Solution {
public:
vector<int> Joseph_circle(vector<int>& people, int k) {
vector<int> v;
int now= 0;
int num= people.size();
for(int i= 0; i<num; i++){
//定位
now= (now+k-1)%people.size();
//插入
v.insert(v.end(),people[now]);
//删除
people.erase(people.begin()+now);
}
return v;
}
};
直接返回的递归和传入引用变量的递归
二叉树的定义具有递归性
Q13:
假设二叉树中的每个结点为单个字符,采用二叉链存储结构存储。
设计一个算法,计算一棵给定二叉树b中的所有单分支结点个数。
#### 答案:
```cpp
typedef struct{
char data;
struct *rchild, *lchild;
}BtNode;
//直接返回
int SingleNodeCount(BtNode* root){
if(root==NULL)return 0;
//if(root->lchild ^ root->rchild) return 1+SingleNodeCount(root->lchild)+SingleNodeCount(root->rchild);
if ((root->lchild==NULL && root->rchild!=NULL) || (root->lchild!=NULL && root->rchild==NULL)){
return 1+SingleNodeCount(root->lchild)+SingleNodeCount(root->rchild);
}
return SingleNodeCount(root->lchild)+SingleNodeCount(root->rchild);
}
//C++ 中,^是异或运算符,用于整数值的运算,而不是用于判断左右孩子的存在与否
//传入引用变量
void SingleNodeCount(BtNode* root, int& count= 0){
if((root->lchild==NULL && root->rchild!=NULL) || (root->lchild!=NULL && root->rchild==NULL)) ++count;
if(root->lchild) SingleNodeCount(root->lchild, count);
if(root->rchild) SingleNodeCount(root->rchild, count);
}
```
Q14:
假设二叉树中的每个结点值为单个字符,采用二叉链存储结构。
设计一个算法,求二叉树b中的最小结点值。
#### 答案:
```cpp
typedef struct{
char data;
struct *rchild, *lchild;
}BtNode;
#include <climits> //确保包含 CHAR_MAX
char Min(BtNode* root){
if(root==NULL) return CHAR_MAX; //空树返回最大值
char minVal= root->data; //假设当前结点值最小
char lMin= Min(root->lchild); //递归找左子树最小值
char rMin= Min(root->rchild); //递归找右子树最小值
// 取最小值
if(lMin<minVal) minVal= lMin;
if(rMin<minVal) minVal= rMin;
return minVal;
}
#include <climits>
void Min(BtNode* root, char& min= CHAR_MAX) {
if(root==NULL)return;
min= (min<root->data) ? min:root->data;
if(root->lchild) Min(root->lchild, min);
if(root->rchild) Min(root->rchild, min);
}
```
Q16:
假设二叉树中的每个结点值为单个字符,采用二叉链存储结构存储。
设计一个算法,求二叉树b中第k层上的叶子结点个数。
#### 答案:
```cpp
typedef struct{
char data;
struct *rchild, *lchild;
}BtNode;
int CountKthLevelLeaves(BtNode* root, int k){
if(k==1){
if(root->lchild==NULL && root->rchild=NULL) return 1;
return 0;
}
int sum= 0;
if(root->lchild) sum+= CountKthLevelLeaves(root->lchild, k-1);
if(root->rchild) sum+= CountKthLevelLeaves(root->rchild, k-1);
return sum;
}
```
Q17:
假设二叉树中的每个结点值为单个字符,采用二叉链存储结构存储。
设计一个算法,判断值为x的结点与值为y的结点是否互为兄弟,假设这样的结点值是唯一的。
#### 答案:
```cpp
typedef struct{
char data;
struct *rchild, *lchild;
}BtNode;
bool IsBrother(BtNode* root, char x, char y) {
if(root==NULL)return false;
if(root->lchild && root->rchild){
auto compare= [x,y](BtNode* left, BtNode* right){
return (left->data==x && right->data==y) || (left->data==y && right->data==x);
};
return compare(root->lchild, root->rchild);
}
return IsBrother(root->lchild, x, y) || IsBrother(root->rchild, x, y);
}
//Lambda 表达式定义: auto 函数名= [捕获列表](参数列表) { 函数体 };
}
Q18:
假设二叉树中的每个结点值为单个字符,采用二叉链存储结构存储。
设计一个算法,采用先序遍历方法求二叉树b中值为x的结点的子孙结点,假设值为x的结点是唯一的。
#### 答案:
```cpp
void Output(BtNode* root){
if(root==NULL) return;
printf("%c\t",root->data);
Output(root->lchild);
Output(root->rchild);
}
void Find(BtNode* root, char x){
if(root==NULL) return;
if(root->data==x){
Output(root->lchild);
Output(root->rchild);
return;
}
Find(root->lchild, x);
Find(root->rchild, x);
}
```
设计一个算法,判断一个字符串s是否为形如"序列1@序列2""模式的字符序列,其中序列1和序列2都不含有 '@' 字符,且序列2是序列1的逆序列。
例如 "a+b@b+a" 属于该模式的字符序列,而 "1+3@3-1"不是。
bool IsTrue(SqString s){
vector<char> v;
int i= 0;
while(i<s.length){
char e= s.data[i];
if(e!='@') v.push_back(e);
else break;
i++;
}
i++;
while(i<s.length){
e= s.data[i];
if(v.size()==0) return false;
if(v.back()!=e) return false;
v.pop_back()
i++;
}
if(v.size()!=0) return false;
return true;
}
采用带头结点的单链表表示链串,每个结点存放一个字符,设计一个算法,将链串s中所有值为x的字符删除,要求算法的时间复杂度为O(n)、空间复杂度为O(1) 。
void DeleteX(LinkString* &s, char x) {
LinkString *pre= s, *p= pre->next;
while(p!==NULL){
if(p->data==x){
pre->next= p->next;
free(p);
p= pre->next;
}
else{
pre= pre->next;
p= p->next;
}
}
}
DFS
假设不带权有向图采用邻接表G存储,设计一个算法,判断其中是否存在经过顶点v的回路(一条回路中至少包含3个不同的顶点)。
int visited[MaxV];
bool Cycle(AdjGraph *G, int u, int v, int d, bool &has){
ArcNode *p;
visited[u]= 1;
d++;
p= G->adjlist[u].firstarc;
while(p!=NULL){
int w= p->adjvex;
if(visited[w]==0)Cycle(G,w,v,d,has);
else if(w==v && d>1){
has= true;
return;
}
p= p->nextarc;
}
}
bool HasCycle(AdjGraph *G, int v){
bool has= false;
Cycle(G,v,v,-1,has);
return has;
}
DFS
假设无向图G采用邻接表存储,设计一个算法,判断图G是否为一棵树,若为树,返回真;否则返回假。
一个无向图G是树的条件:无向图联通且无回路或无向图联通只有n-1条边
int visited[MaxV];
void DFS(AdjGraph *G, int v, int &vn, int &en){
ArcNode *p;
visited[v]= 1; vn++;
p= G->adjlist[v].firstarc;
while(p!=NULL){
en++;
if(visited[p->adjvex]==0) DFS(G, p->adjvex, vn, en);
p= p->nextarc;
}
}
bool IsTree(AdjGraph *G){
int vn= 0, en= 0;
for(int i= 0; i<G->n; i++) visited[i]= 0;
DFS(G,1,vn,en);
if(vn==G->n && en==2*(G->n-1)) return true;
else return false;
}
设不带权无向图G采用邻接表表示,设计一个算法求源点i到其余各顶点的最短路径长度。
法一Dijkstra算法,法二广度优先遍历 BFS
int visited[MaxV];
void BFS(AdjGraph *G, int i){
int qu[MaxV],level[MaxV];
int front= 0, rear= 0;
ArcNode *p;
visited[i]= 1;
rear++; qu[rear]= i; level[rear]= 0;
while(front!=rear){
front= (front+1)%MaxV;
int k= qu[front];
int lev= level[front];
if(k!=i)printf("顶点%d到顶点%d的最短距离是:%d",i,k,lev);
p= G->adjlist[k].firstarc;
while(p!=NULL){
if(visited[p->adjvex]==0){
visited[p->adjvex]= 1;
rear= (rear+1)%MaxV;
qu[rear]= p->adjvex;
level[rear]= lev+1;
}
p= p->nextarc;
}
}
}

5万+

被折叠的 条评论
为什么被折叠?



