算法题笔记第二周加油

课程目录

1、递归基础知识

//le-509
class Solution {
public:
    int fib(int n) {
        if(n==0) return 0;
        if(n==1) return 1;
        else
            return fib(n-1) + fib(n-2) ;
    }
};

2、冒泡排序基础知识

O(n2)

#include<iostream>
using namespace std;

void f(int a[], int n){
    for(int i=0; i<n-1; i++){
        for(int j=0; j<n-i-1; j++){
            if(a[j] > a[j+1]){
                int temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp; j+1, 不是j+i,莫写错了
            }
        }
    }
}
void print(int a[], int n){
    for(int i=0; i<n; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main()
{
    int length;
    cin >> length;
    int i=0;
    int a[1000]={0};
    while(i < length){
        cin >> a[i++];
    }
    cout << "原数组:"<<endl;
    print(a,length);
    f(a, length);
    cout << "冒泡后:"<<endl;
    print(a,length);
    
    return 0;
}

3、选择排序基础知识

O(n2)

#include<iostream>
using namespace std;

void f(int a[], int n){
    for(int i=0; i<n-1; i++){
        int index = i;
        for(int j=i+1; j < n; j++){
            if(a[j] < a[index]){
                index = j; //index是最小元素的下标
            }
        }
        int temp = a[i]; 
        a[i] = a[index];
        a[index] = temp; //每次循环都是把最小元素调到最前面
    }
}
void print(int a[], int n){
    for(int i=0; i<n; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main()
{
    int length;
    cin >> length;
    int i=0;
    int a[1000]={0};
    while(i < length){
        cin >> a[i++];
    }
    cout << "原数组:"<<endl;
    print(a,length);
    f(a, length);
    cout << "选择排序后:"<<endl;
    print(a,length);
    
    return 0;
}

4、插入排序基础知识

O(n2)


5 1 3 4 2 
#include<iostream>
using namespace std;

void f(int a[], int n){
    for(int i=1; i<n ;i++){
        int key = a[i];
        int j = i-1;
        while(j >= 0 && a[j]>key){
            a[j+1] = a[j];
            j--;
        }
        a[j+1] = key;
    }
    
}
void print(int a[], int n){
    for(int i=0; i<n; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main()
{
    int length;
    cin >> length;
    int i=0;
    int a[1000]={0};
    while(i < length){
        cin >> a[i++];
    }
    cout << "原数组:"<<endl;
    print(a,length);
    f(a, length);
    cout << "插入排序后:"<<endl;
    print(a,length);
    
    return 0;
}

5、快速排序基础知识

#include<iostream>
using namespace std;

int part(int nums[], int left, int right){
    int pivot = nums[left];
    while(left < right){
        while(left<right && nums[right]>pivot){
            right--;
        }
        nums[left] = nums[right];
        while(left < right && nums[left] <= pivot){
            left++;
        }
        nums[right] = nums[left];
    }
    nums[left] = pivot;
    return left;
}

void quickSort(int a[], int left, int right){
    if(left >= right){
        return;
    }
    int mid = part(a,left,right);
    quickSort(a,left,mid-1);
    quickSort(a, mid+1, right);
}

void f(int a[], int n){
    quickSort(a, 0, n-1);
}
void print(int a[], int n){
    for(int i=0; i<n; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main()
{
    int length;
    cin >> length;
    int i=0;
    int a[1000]={0};
    while(i < length){
        cin >> a[i++];
    }
    cout << "原数组:"<<endl;
    print(a,length);
    f(a, length);
    cout << "快速排序后:"<<endl;
    print(a,length);
    
    return 0;
}

7、归并排序

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
void print_arr(int arr[], int n){
    for(int i=0;i<n;i++){
        printf("%d ", arr[i]);
    }
    putchar('\n');
}
//合并
void merge(int arr[], int tempArr[],int left,int mid,int right){
    //标记左半区第一个未排序的元素
    int l_pos = left;
    //标记右半区第一个未排序的元素
    int r_pos = mid+1;
    //临时数组元素的下标
    int pos = left;
    //合并
    while(l_pos <= mid && r_pos <= right){
        if(arr[l_pos] < arr[r_pos])
            tempArr[pos++] = arr[l_pos++];
        else
            tempArr[pos++] = arr[r_pos++];
    }
    //合并左半区剩余元素
    while(l_pos <= mid)
        tempArr[pos++] = arr[l_pos++];
    //合并右半区剩余元素
    while(r_pos <= right)
        tempArr[pos++] = arr[r_pos++];
    //把临时组数中合并后的元素复制回原来的数组
    while(left <= right){
        arr[left] = tempArr[left];
        left++;
    }
}
void msort(int arr[],int tempArr[],int left, int right){
    //如果只有一个元素,就不需要划分
    //只有一个元素的区域,本身就是无序的,只需要被归并
    if(left < right){
        int mid = (left+right)/2;
        //递归划分左半区域
        msort(arr,tempArr,left,mid);
        //递归划分右半区域
        msort(arr,tempArr,mid+1,right);
        merge(arr, tempArr, left,mid,right);
    }
}
void merge_sort(int arr[], int n){
    //分配一个辅助数组
    int *tempArr = (int *)malloc(n * sizeof(int));
    if(tempArr){//辅助数组分配成功
        msort(arr,tempArr,0,n-1);
        free(tempArr);
    }
    else{
        printf("error: failed to allocate memory");
    }
} 


int main()
{
    int arr[] = {9,5,2,7,12,4,3,1,11};
    int n=9;
    print_arr(arr,n);
    merge_sort(arr, n);
    print_arr(arr,n);
    return 0;
}
归并排序的课堂版
#include<iostream>
using namespace std;
#include "dayin.hpp"
void merge(int arr[], int reg[], int start,int end)
{
    if(start >= end){
        return ;
    }
    int len =end-start, mid = (len>>1) + start;
    int start1=start, end1=mid;
    int start2 =mid+1, end2 = end;
    merge(arr,reg,start1, end1);
    merge(arr, reg, start2,end2);
    int k = start;

    while(start1<=end1 && start2 <= end2)
        reg[k++] = arr[start1] < arr[start2] ? arr[start1++]:arr[start2++];
    while(start1 <= end1){
        reg[k++] = arr[start1++];
    }
    while(start2 <= end2){
        reg[k++] = arr[start2++];
    }
    for(k=start; k <= end;k++){
        arr[k] = reg[k];
        cout << " arr[k]"<< arr[k] << " ";
    }
    cout << endl;
    

}



int main()
{
    int length;
    cin >> length;
    int i=0;
    int a[1000]={0};
    while(i < length){
        cin >> a[i++];
    }
    cout << "原数组:"<<endl;
    print(a,length);
    int reg[10]={0};

    merge(a, reg, 0,length-1);

    cout << "归并排序后:"<<endl;
    print(a,length);
    
    return 0;
}

8、剑指offer 40. 最小k个树

9、剑指offer 41.数据流中的中位数

10、剑指offer 51.数组中的逆序对

11、合并k个升序链表

12、合并两个有序数组

13、颜色分类

14、部分排序

15、计算右侧小于当前元素个数

16、有序数组的平方

17、盛最多水的容器

//le-11
class Solution {
public:
    int maxArea(vector<int>& height) {
        int res = 0,s;
        int left = 0, right = height.size()-1;
        while(left < right){
            if(height[left] <= height[right]){
                s = height[left] * (right-left);
                if(s > res) res = s;
                left++;
            }
            else{
                s = height[right] * (right-left);
                if(s>res) res = s;
                right--;
            }
        }
        return res;
    }
};

18、两数之和

//le-1
class Solution{
public:
    vector<int> twoSum(vector<int> &nums,int  target){
        unordered_map<int,int> m;
        for(int i=0; i < nums.size(); i++){
            int t = target - nums[i];
            if(m.count(t) == 1){
                return vector<int>{m[t],i};
            }
            m[nums[i]] = i;
        }
        return vector<int>();
    }
};

19、分发饼干

20、柠檬水找零

21、用最少数量的箭引爆气球

22、移掉k位数字

23、跳跃游戏

24、摆动序列

25、三数之和

26、最接近三树之和

27、加油站

28、合并区间

li1倒着输出

输入这种“I love China!”,然后你输出"China! love I",哈哈哈,双相奔赴

#include <cstdio>
#include <cstring>

int main()
{
	char a[100] = { "I love China!" };
	//char a[100] = { "the"};
	int len = strlen(a);
	char b[100] = { 0 };
	for (int i = len; i >= 0; i--)
	{
		int j = 0;
		while (a[i] != ' '&&i>=0)
		{
			b[j++] = a[i];
			i--;
		}
		//printf("%s ", b);
		for (int k = j; k >= 0; k--)
		{
			printf("%c", b[k]);
		}
		printf(" ");
		memset(b, 0, sizeof(b));
	}

	return 0;
}

li2输出最小公倍数

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>

int gcd(int a, int b)
{
	if (b == 0)
	{
		return a;
	}
	return gcd(b, a % b);
}

int main()
{
	int a, b;
	char c;
	while (1)
	{
		printf("continue or quit: ");
		scanf("%c", &c);
		if (c == 'Y' || c == 'y')
		{
			printf("please input two numbers: ");
			scanf("%d %d", &a, &b);
			printf("%d 和 %d 的最小公倍数是: %d\n", a, b, (a * b) / gcd(a, b));
			getchar();
		}
		else
		{
			break;
		}
	}
	return 0;
}

在这里插入图片描述

li3求字符串的回文子串个数

一开始有点头大,不知道怎么分析,看了网上的例题过后有点思路了,总体就是回文字串长度入手,要么这个回文子串长度是奇数,要么是偶数,奇偶分开,就不会有考虑到判断重复的字符串了。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>

int cnt;

void func(int i, int j, int len, char a[])
{
	while(i >= 0 && j < len && a[i] == a[j] )
	{
		cnt++;
		i--;
		j++;
	}
}


int main()
{

	char a[100] = { 0 };
	scanf("%s", a);
	int len = strlen(a);
	for (int i = 0; i < len; i++)//从每一个元素开始找,从这个元素为中心,找奇数个子串回文数个数,和偶数个的子串回文数个数
	{
		func(i,i,len,a);
		func(i,i+1,len,a);
	}
	printf("cnt = %d\n", cnt);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值