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

自适应的网站可以看男男做的视频网站

自适应的网站,可以看男男做的视频网站,seo需要付费吗,百度seo排名优化如何目录 前言 1、题1 只出现一次的数字 : 解法一:遍历 参考代码: 解法二:按位异或 参考代码: 解法三:哈希表 参考代码: 2、题2 杨辉三角: 参考代码: 总结 前言 …

目录

前言

1、题1 只出现一次的数字 :

解法一:遍历

参考代码:

解法二:按位异或

参考代码:

解法三:哈希表

参考代码:

2、题2 杨辉三角:

参考代码:

总结


前言

路漫漫其修远兮,吾将上下而求索;


大家可以自己先尝试做一下:

136. 只出现一次的数字 - 力扣(LeetCode)

118. 杨辉三角 - 力扣(LeetCode)


1、题1 只出现一次的数字

136. 只出现一次的数字 - 力扣(LeetCode)

解法一:遍历

利用双指针,一个指针定位一个指针去遍历后续的数字看是否有重复的;

参考代码:

    int singleNumber(vector<int>& nums) {int n = nums.size();if(n==1) return nums[0];//解法一:遍历for(int i = 0;i<n;i++){int flag = 1;for(int j = 0;j<n;j++){if(j!=i && nums[i] == nums[j]) flag = 0; }if(flag) return nums[i];}return 0;//此处的返回没有意义,随便返回就可以了}

解法二:按位异或

按位异或的特点:相同为0,相异为1;非空数组nums 中只有一个数字出现了1次,其余的均出现了2次,将nums 中的数据全部进行按位异或,相同的数据抵消就会得到那个只出现一次的数;

参考代码:

    int singleNumber(vector<int>& nums) {//按位异或int ret = 0;for(auto e: nums) {ret ^= e;}return ret;}

解法三:哈希表

将nums 中的数据放入hash 之中,看哪一个数字出现了一次即可;

参考代码:

    int singleNumber(vector<int>& nums) {//hashunordered_map<int,int> hash;//<数据,出现的次数>for(auto e: nums){hash[e]++;}for(auto e:hash){if(e.second == 1) return e.first;}return 0;//随便返回一个}

2、题2 杨辉三角:

118. 杨辉三角 - 力扣(LeetCode)

如果用C语言解决的话,需要返回一个二级指针:

本题用C语言做会非常恶心,可以将杨辉三角想象成二维数组,只是不同的是它不是 m*n 的每一行的数据个数均相等的,杨辉三角的每一行的个数是变化的;

用C语言不能直接静态开辟一个二维数组,只能通过动态开辟的方式;

Q:如何动态开辟一个二维数组?

  • 将杨辉三角想象成一个直角三角形;杨辉三角画成等腰三角形其本质是一个逻辑结构(想象出来的结构);

  • 用C语言做动态开辟数组:先开辟指针数组,然后造一个循环开辟每一行;并且释放的时候也要注意,不能直接释放指针数组,需要写一个循环先将指针数组中所指向的数组先释放(先释放局部再释放整体);

由于C语言只支持一次即返回一个值,而如果想要返回多个值,想让别人拿到该数组的大小只能通过传址传参;在leetcode 之中要写通用的代码,凡是返回数组(返回指向该数组的指针),就得告诉这个数组有多少行,此时写测试用例的时候,每个题都要有每个题的情况;

因为返回一个一维数组需要知道这个一维数组中有多少个数据,同理,返回一个二维数组就需要知道二维数组有多少行,并且一行中有多少个数据;所以其第三个参数,指的是所要返回这个二维数组每一行中有多少个数据;

Q:第三个参数为什么是二级指针呢?

  • 二维数组中每一行的数据个数可能是不同的,需要开辟一块空间来记录每一行的数据个数;所以就需要传一个地址的地址,即二级指针;

我们此处用C++来解决:

Q: 如何理解 vector<vector<int>> ?

  • 在vector 中存放vector<int> ; vector 的底层:
template<class T>
class vector
{
private:T* _a;size_t _size;size_t _capacity;
};

Q: vector<vector<int>>是如何开辟需求的二维数组?

	vector<vector<int>> vv(numRows);//开辟numRows行for (int i = 0; i < numRows; ++i)//开辟每一行{vv[i].resize(i + 1, i);}

vector<vector<int>> 会实例化出两个类,vector<int> 是一个类,而vector<vector<int>> 是另外一个类;

vector<int> 实例化:

vector<vector<int>> 实例化:

类模板给不同的模板参数就会生成不同的类型;这两个虽然是从同一个模板中实例化出来的,但是他们的类型不同,一个是 int  ,一个是 vector<int>;

vector<vector<int>> 是一个对象数组其每一个位置上是一个 vector<int> 对象;

我们在开辟每一行的时候用resize 进行初始化,而并非使用reserve , 这是因为reserve 只会开辟空间而并未插入数据;而resize ,当 n>capacity  或 size<n<capacity 的时候会插入数据,相当于用resize 既可以开辟空间又会初始化;

需要注意的是,已经存在的对象想要初始化就只能使用resize

一个vector 想要初始化有两种方式:

  • 1、在构造的时候进行初始化;
  • 2、构造之后利用resize 进行初始化;

基于杨辉三角的特点,我们需要将开辟的二维数组中的空间均初始化为1,如下:

而接下来就需要处理杨辉三角中其他剩余的值了;访问 vector<vector<int>> 中的数据可以通过二维数组的访问形式进行访问: vv[i][j] , 但是其底层与二维数组的访问完全不同

在回答“ vv[i][j]的底层与二维数组的访问完全不同” 的问题之前,我们先了解一下C语言中二维数组的两种开辟方式:

对于二维数组:eg.int aa[10][5] , 10 行 5 列的二维数组本质上也是一维数组;

  • 1、动态开辟二维数组需要进行转换;
	int* aa = (int*)malloc(sizeof(int*) * N);for(int i = 0; i < N; ++i){aa[i] = (int*)malloc(sizeof(int) * (i + 1));}

aa 作为二维数组数组名,表示该数组的首元素地址,即指向该指针数组;aa[i] 则是访问指针数组中的所对应的数据,而指针数组的元素本身就是一级指针,那么 aa[i][j] 就是两次解引用,访问到了二维数组中的数据;动态开辟的二维数组是两次指针的解引用,先进行第一层的解引用拿到指针数组中的元素,再进行第二层的解引用,拿到真实存放的数据;

  • 2、静态开辟的二维数组,是转换成一个一维数组;

eg.int aa[10][5];

C语言中的静态二维数组其实在底层其实是一个一维数组,那么 int aa[10][5];是一个有50个int 类型空间的一维数组,即一次解引用就可以解决(会通过一些计算来实现一次解引用);

总之,动态开辟和静态开辟是不一样的;

C++中,对于vv[i][j]而言,是两次函数调用对于C语言来说,静态开辟的一维数组或者二维数组均是一次解引用实现数据的访问,数组的访问本质上均会转换成指针的访问,所以C语言的访问数组中的元素一定会转换成对指针的解引用;

Q:vv[i][j] 如何转换成两个函数调用?

  • 首先,vv[i][j] 会转化成 vv.operator[](i).operator[](j) ;其中 vv.operator[](i) 返回的是 vector<int> 的对象,而vector<int>.operator[](j) 返回值为 int 对象相当于第一个 operator[] 的调用返回了vector<int> 对象又会作为下一次调用 operator[] 的左操作数,此时返回值为 int 类型的对象;于是乎就相当于拿到了第 i 行第 j 个对象;

Q: 相较于我们之前使用的二维数组(C语言中的二维数组),此处使用vector<vector<int>> 的好处是什么?

  • vector<vector<T>> 的功能更加强大在C语言中以前定义的静态数组,静态数组中的每一行的数据个数均是固定的,由于C语言不支持变长数组,其行、列必须是常量,且无论是申请还是释放都需要亲历亲为,比较麻烦;但是倘若使用 vector<vector<>> ,便就不存在这样的问题,无需管释放(C++中会自动调用析构函数),并且其每一行的数据个数为多少均无所谓, 即不会强制每一行的数据个数均需要一样;

vv[i][j] 看似有两个[ ], 实际上结合底层的角度它是调用了两个类实例化出来的operator[] ,而这两个类又是由 vector<T> 实例化出来的。由 vector<T> 实例化出来两个类 vector<int> 和 vector<vector<int>> ,然后再实例化其成员函数;

解题:

 

需要从第2行开始遍历,而一有 vv.size() 行;

对于每一行元素访问的控制j ; 每一行的数据个数是不固定的,从每一个 vector<vector<int>> 对象的 _size 可以得知每一行中数据的个数,即 vv[i].size() 为第 i 行中的数据个数;对于杨辉三角来说,其每一行的第一个和最后一个无需进行访问,我们在开辟空间初始化的时候就可以完成;

杨辉三角的计算规则:

  • 将杨辉三角看作是一个直角三角形:

通过观察杨辉三角的计算规则和下标的关系,我们可以得到: [i,j] = [i-1 , j] + [i-1 , j-1];

参考代码:

    vector<vector<int>> generate(int numRows) {vector<vector<int>> vv(numRows);for(size_t i = 0;i<numRows;++i){vv[i].resize(i+1,1);}//填for(int i = 2;i<vv.size();++i)//从2行开始{for(int j = 1; j<vv[i].size()-1;++j){//第一个和最后一个不用填vv[i][j] = vv[i-1][j] + vv[i-1][j-1];}}return vv;}

总结

1、在C++中中,vector<vector<int>> 用vv[i][j] 访问数据会转化调用两个函数,即 vv.operator[](i).operator[](j)

2、其中 vv.operator[](i) 返回的是 vector<int> 的对象,而vector<int>.operator[](j) 返回值为 int 对象相当于第一个 operator[] 的调用返回了vector<int> 对象又会作为下一次调用 operator[] 的左操作数,此时返回值为 int 类型的对象;于是乎就相当于拿到了第 i 行第 j 个对象;

http://www.dtcms.com/wzjs/808127.html

相关文章:

  • 如何设计网站的首页姑苏美食标题网页设计素材
  • 徐州教育学会网站建设营销策划书格式及范文
  • 米定制网的网站是那个公司做网页视频下载器app
  • phpstorm网站开发wordpress站点地址修改
  • 网页设计与网站制作百度域名值多少钱
  • 网站建设实训教程网站名称 中国 备案
  • 第一次找人做网站互联网推广渠道有哪些
  • 黄冈网站制作公司电子商务平台中搜索词拆解时
  • 一站式网站开发服务平台wordpress流媒体
  • wordpress代码修改用户权限东莞seo建站广告费
  • 网站源码检测张家口北京网站建设
  • 房地产网站方案上海哪里有网站建设
  • 移动端网站建设的意义wordpress 响应式 企业
  • 网站的制作流程网站开发前端指什么软件
  • 网站设计确认怎么查网站的空间商
  • 网站美工难做吗wordpress page 分页
  • 网站收录很慢个人免费网站注册com
  • 沙井网站建设公司做中英文网站的
  • python 网站开发实例教程做php网站用什么软件好
  • 建设vip网站相关视频下载好的移动端网站模板下载
  • 小米果怎么做视频网站网站建设文化方案
  • 赣州信息港网东莞百度搜索优化
  • 企业网站托管如何更有效购物网站开发背景
  • 请问如何做网站wordpress 展示类主题
  • 网站建设家乡网页设计模板html5做网站总结
  • 建筑工程招聘最新信息平台吉林百度seo公司
  • 网站建设邀标比选网站开发与管理学什么
  • 门户网站介绍国外海报设计网站
  • 什么是展示型网站建筑八大员报考时间和条件
  • 网站建设公司图片岳阳做网站 公司电话