当前位置: 首页 > news >正文

[算法周训 3] 字符串训练2

本周的算法周训大多属于杂项级别,但大多属于字符串系列,故依旧放在字符串中了。由于我本周事情较多,该博客也是一拖再拖,本来周末需要写的,但是拖到了现在。(写博客的时候自己重新打了一遍代码,使自己又熟悉一遍)

在此过程了,我也发现部分C++的特性没有使用到位,大多都是C with STL,说起来还是蛮惭愧的,所以我也在部分知识点回顾中写了一些我遇到的问题。接下来我也会有意识地去接触新的C++ 特性。不过倒是发现,C++特性倒是有点python的味道了。

希望对你有所帮助!

目录

  • 部分知识点回顾
  • 重塑矩阵
  • 最长和谐子序列
  • 验证回文串
  • 旋转图像
  • 二进制求和
  • 汇总区间

部分知识点回顾

构造二维数组(vector),规定行数r,列数为c

vector<vector<int>> ans (r,vector<int>(c));

遍历map:
我之前的做法就是使用迭代器,

map<int,int> a;
map<int,int> ::iterator it = a.begin();
for(;it!=a.end();++it){
	keyname = it->first;
	value = it->second;
}

这个C++特性我倒是蛮喜欢的,又方便又简洁。

map<int,int> a;
for(auto &[num,count] : a) {
	a.count(key_name);
	cur_key_name = a[num]
}

c++ 遍历与字符类函数:
这种遍历倒是有点Python的味道了!

		for (char ch: s) {
            if (isalnum(ch)) {
                sgood += tolower(ch);
            }
        }

重塑矩阵

在这里插入图片描述
分析题目,比较简单,就是单纯地遍历。不过需要考虑是否能满足行列乘积为总数目的要求。
在这里我先用一个数组全部读进去,然后就是简单的遍历,总体上难度简单。

class Solution {
public:
    vector<vector<int>> matrixReshape(vector<vector<int>>& mat, int r, int c) {
        vector<vector<int> > a;
        vector<int> tmp;
        int row = mat.size();
        int col = mat[0].size();
        if( row * col != r*c) {
            return mat;
        }
        vector<int> cx;
        for(int i=0;i<mat.size();i++) {
            for(int j=0;j<mat[0].size();j++) {
                cx.push_back(mat[i][j]);
            }
        }
        int be = 0;
        for(int i=0;i<r;i++) {
            tmp.clear();
            for(int j=0;j<c;j++) {
                tmp.push_back(cx[be]);
                be ++;
            }
            a.push_back(tmp);
        }
        return a;
    }
};

当然了,这个题目可以不这么做,上面的做法是偏向常规解题的。我们注意到一个行数为m,列数为n,行列下标都从0开始编号,那么(i,j)对于一维位置就是i*n + j。(类似就是把二维数组用数字把一维表达了出来)。所以我们就有了一维数组的坐标,假定是x.那么也可以根据一维数组来反求二维数组中去,其对应的(i,j)为 i = x/n ,j = x%n.

vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
	int m = nums.size();
    int n = nums[0].size();
    if (m * n != r * c) {
        return nums;
    }
	
	vector<vector<int>> ans (r,vector<int>(c));
	for(int x = 0;x< m*n ; ++x) {
		ans[x/c][x%c] = nums[x/n][x%n];
	}
	return ans;
}

最长和谐子序列

在这里插入图片描述
这个题目寻找最大值和最小值为1,这里就有多种办法(例如使用sort)注意到子序列的定义,我一开始以为是不能改变数组,这导致我就没有使用sort而陷入了僵局。因为sort将会改变数组的元素顺序。
但是我们注意到,结果只要输出数组length就可以了,这意味着我们可以不用求出元素本来的顺序,只要知道length就可以了,问题就变得很显然了。
那么我这里使用map来进行保存数组,(比较map也封装好了排序)

class Solution {
public:
    int findLHS(vector<int>& nums) {
        map<int,int> a;
        for(auto & e : nums) {
            a[e]++;
        }
        int res = 0;
        for(auto &[num,count] : a) {
            if(a.count(num+1)) {
                res = max(res,a[num+1]+count);
            }
        }
        return res;
    }
};

当然了,常规方法就是sort了。不过需要使用滑动窗口来进行求解:

int findLHS(vector<int>& nums) {
	sort(nums.begin(),nums.end());
	int n = nums.size();
	int ans =0,left =0,right = 0;
	while(right < n ) {
		while(left < right &&nums[right]-nums[left] >1){
		left ++;
		}	
		if(nums[right] - nums[left] == 1) {
		ans = max(ans,right-left +1);
		
		}
	right++;
	}
	return ans;
}

验证回文串

在这里插入图片描述
题目我倒是没看清,简单来说就是字母留下数字留下,然后判断是否是回文串了。
前期工作,我的思路就是把字母改成小写,然后把数字留下,比较简单:

class Solution {
public:
    bool isPalindrome(string s) {
        string str = "";
        int len = s.size();
        string m =""; 
        for(int i=0;i<len;i++ ) {
            if(s[i] >= 'a' && s[i] <='z' || s[i] >='0' && s[i] <='9' ) {
                str += s[i];
            }
            if( s[i] >='A' && s[i] <= 'Z') {
                str += s[i] - 'A' + 'a';
            }

            if(s[len-1-i] >= 'a' && s[len-1-i] <= 'z' || s[len-1-i] >= '0' && s[len-1-i] <= '9') {
                m += s[len-1-i];
            }
            if(s[len-1-i] >='A' && s[len-1-i] <='Z') {
                m += s[len-1-i] -'A' +'a';
            }
        }

        return m == str;
        
    }
};

方法一就是简单的思路,但同时可以使用库函数:

	for (char ch: s) {
            if (isalnum(ch)) {
                sgood += tolower(ch);
            }
        }

当然了,也可以使用双指针,主要就是判断。主体思想就像折半查找

while (left < right) {
           if (sgood[left] != sgood[right]) {
                return false;
            }
            ++left;
            --right;
        }

旋转图像

在这里插入图片描述
这题目我一开始比较没看出来。后来我找到了规律,规律如下:
以样例输入输出为例。查找输入最后一组数组,7,8,9对应的输出的第一列。后面倒数第二组4,5,6也是同样的,就是第二列。以此类推,发现规律这题非常简单,由于使用c++ vector较为繁琐,故这题使用Java还是比较简单的.
一开始我认为java数组和c++ vector一样,使用了matrix = tmp来进行了拷贝,发现不行,所以还是采用了for语句来进行循环遍历了。

class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
       int [][] tmp = new int[n][n];
       int cnt =0;
       int row = 0;
       for(int i=n-1;i>=0;i--) {
           row = 0;
           for(int j=0;j<n;j++) {
               
               tmp[row][cnt] = matrix[i][j];
               row++;
           }
           cnt++;
       }
        for(int i=0;i<n;i++) {
            for(int j=0;j<n;j++) {
                matrix[i][j] = tmp[i][j];
            }
        }
    }
}

c++ 写法,主要就是交换。主要思想和我前面找规律还是有共通之处的。

class Solution {
public:

    void rotate(vector<vector<int>>& matrix) {
        auto a = matrix;
        for(int i=0;i<matrix.size();i++) {
            for(int j=0;j<matrix[0].size();j++) {
                a[j][matrix.size()-i-1] = matrix[i][j];
            }
        }
        matrix = a;
    }
};

当然了,这个还有最直接的办法,就是先转置后镜像对称。

二进制求和

在这里插入图片描述
别的不说,大数求和模板题目,必须要背住格式!

class Solution {
public:
    string addBinary(string a, string b) {
        string str = "";
        int cur =0,i = a.size()-1,j = b.size()-1;
        while( i >= 0 || j >= 0 || cur != 0) {
            if(i >= 0) cur += a[i--]-'0';
            if(j >= 0) cur += b[j--] - '0';
            str += to_string(cur % 2);
            cur /= 2;
        }
        reverse(str.begin(),str.end());
        return str;
    }
};

汇总区间

在这里插入图片描述
先说一下我自己的思路,我也是一次遍历,不过看num[i]需要判断后继一个是否是相差1的数,否则就继续下去,不过代码能运行一半,后面错误有些多,故没有完成100%,这里将我的思路代码贴出来。

class Solution {
public:
    vector<string> summaryRanges(vector<int>& nums) {
        vector<int > a;
        vector<string> ve;
        int flag = 0;
        for(int i=0;i<nums.size()-1;i++) {
            if(nums[i] == nums[i+1] - 1) {
                a.push_back(nums[i]);
            }else {
                if( (nums[i] == nums[i-1] +1 ) && i >=1) a.push_back(nums[i]);
                string str = "" ; 

                int  be = a[0];
                int end = a[a.size()-1];
                if(be == end) {
                    str += be;
                    ve.push_back(str);
                    }else {
                    str += to_string(be);
                    str += "->";
                    str += to_string(end);
                    ve.push_back(str);
                }
                a.clear();
            }
        }
        string s = ve[ve.size()-1];
        int ns = int(s[s.size()-1]);
        if( ns == nums[nums.size()-1] - 1) {
            ve.pop_back();
            s[s.size()-1] =  nums[nums.size()-1] - '0';
            ve.push_back(s);
        }else {
            string m = "";
            m += to_string(nums[nums.size()-1]);
            ve.push_back(m);
        }
        return ve;
    }
};

当然了这个题本质使用双指针来进行操作。

class Solution {
public:
    vector<string> summaryRanges(vector<int>& nums) {
        vector<string> ret;
        int i = 0;
        int n = nums.size();
        while (i < n) {
            int low = i;
            i++;
            while (i < n && nums[i] == nums[i - 1] + 1) {
                i++;
            }
            int high = i - 1;
            string temp = to_string(nums[low]);
            if (low < high) {
                temp.append("->");
                temp.append(to_string(nums[high]));
            }
            ret.push_back(move(temp));
        }
        return ret;
    }
};

相关文章:

  • 判断月份所在的季节
  • 大数据毕设选题 - flask疫情数据可视化系统(python)
  • 记录第一次开源流计算框架Flink代码的贡献
  • 共码未来 | 助力实现事半功倍的前端开发体验
  • 客户端存储localStorage和sessionStorage以及Cookie
  • Python学习笔记:Jupyter Notebook快速入门案例:学习时间与成绩的关系
  • 嵌入式软件工程师面试题(三)
  • K8S搭建共享存储(以MySQL例)
  • 【C++】类和对象(中篇)(万字)
  • 虹科教您 | 虹科TSN配置软件RELY-TSN-Configurator基本操作指南
  • 【python基础】super是啥,你会用吗?
  • 反向传播和其他微分算法
  • 爆肝撸了个“羊了个羊”通关助手
  • Flutter快学快用17 打包发布:Flutter 应用,你离线上运营只差最后一步
  • 效果超强!基于Prompt Learning、检索思路实现文本分类,开源数据增强、可信增强技术
  • 【Leetcode】101. 对称二叉树
  • 【RocksDB】TransactionDB源码分析
  • js递归,无限分级树形折叠菜单
  • JS基础之数据类型、对象、原型、原型链、继承
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • React Native移动开发实战-3-实现页面间的数据传递
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • 从0实现一个tiny react(三)生命周期
  • 反思总结然后整装待发
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 力扣(LeetCode)56
  • 如何选择开源的机器学习框架?
  • 收藏好这篇,别再只说“数据劫持”了
  • 数据仓库的几种建模方法
  • 一个项目push到多个远程Git仓库
  • 源码安装memcached和php memcache扩展
  • 选择阿里云数据库HBase版十大理由
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (MATLAB)第五章-矩阵运算
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (转)【Hibernate总结系列】使用举例
  • (转)linux下的时间函数使用
  • . NET自动找可写目录
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .net core 6 集成和使用 mongodb
  • .net 受管制代码
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .Net的DataSet直接与SQL2005交互
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • .NET面试题(二)