自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

原创 Lua元表应用___数据检查

1. 前言在游戏项目中,Lua一般被广为使用在UI界面上,因为其轻巧,简便,支持热更新等特点。当然,有的游戏的单局中也使用了Lua。然而Lua语言的缺点也很明显,因为是弱类型语言,有的编码上的错误不容易被发现。例如变量名的错误拼写并不会带来编译的错误。比如游戏中有个配置文件,存放了各个数据模型的定义:DataModelDef = DataModelDef or{}DataModelDef.FubenConfigDataModel ={ FubenId = 0; Fuben

2020-06-20 22:38:09 96

原创 【Lua 5.3源码】虚拟机指令分析(三) 赋值指令

1. 赋值指令Lua中的赋值指令有如下几个:OP_MOVE A B R(A) := R(B)OP_LOADK A Bx R(A) := Kst(Bx)OP_LOADKX A R(A) := Kst(extra arg)OP_LOADBOOL A B C R(A) := (Bool)B; if (C) pc++OP_LOADNIL A B R(A), R(A+1), …, R(A+...

2019-12-21 22:10:26 162

原创 【Lua 5.3源码】虚拟机指令分析(二)

1. Proto函数原型任何一个函数,一个 lua 文件, 经过编译之后都会对应变成Lua的一个LClosure(闭包)对象,一个闭包包含一个函数原型(Proto)和一个upvalues列表。typedef struct LClosure { ClosureHeader; struct Proto *p; UpVal *upvals[1]; /* list of upvalues...

2019-12-21 13:07:02 86

原创 LeetCoder_____ 不同路径Ⅱ(63)

1. 思路跟上一个题目相比,添加了路障,其实对于有路障的题目也可以用组合数来做,需要用到组合数+容斥定理,详情可以参见我之前出的一个题目:亡灵峡谷不过这里因为N,M足够小,所以可以使用动态规划进行求解,在上一个题目的基础上呢,我们只需要将有障碍的dp值为0即可。2. 代码class Solution {public: int uniquePathsWithObstacles(v...

2019-12-15 22:15:54 67

原创 LeetCoder_____ 不同路径(62)

1. 思路A看题目比较简单,有两种做法,第一种做法是数学方法,从左上走到右下,要横着走N-1次,竖着走M-1次,那么其实就是在M+N-2次中选择其中N-1次横着走。这就变成了一个组合数学问题。即是:Cm+n−2n−1C^{n-1}_{m+n-2}Cm+n−2n−1​不过需要注意的是溢出问题。2. 代码Aclass Solution {public: int uniquePath...

2019-12-15 22:00:21 50

原创 LeetCoder_____ 旋转链表(61)

1. 思路较为简单的一个链表操作题目,只需要找到链表的长度L,移动的长度对链表的长度取模就是真实的移动距离K。将链表头尾相接,然后再将第L-K-1和第L-K个节点分开就是最后的结果。不过需要注意的是特殊情况,比如移动距离为0,以及链表是个空链。2. 代码/** * Definition for singly-linked list. * struct ListNode { * ...

2019-12-10 21:39:29 58

原创 【Lua 5.3源码】虚拟机指令分析(一)

1. Lua虚拟机简介Lua VM 使用的是 基于寄存器的虚拟机(Register-based)。 指令都是在已经分配好的寄存器中存取操作数。add a b c 将 寄存器 b 与 寄存器 c 中的值相加,结果存在 寄存器 a 中。 标准的三地址指令,每条指令的表达能力很强,并有效的减少了内存赋值操作。ADD C,A,B //将A,B寄存器里面的值相加后赋值给C寄存器除此之外还有一种虚...

2019-12-08 18:35:22 204

原创 LeetCoder_____ 第k个排列(60)

1. 思路康拓展开,具体思路如下:对于1,2,3,4的所有排列,假如找第15个:我们知道确定第一个元素,其余三个的所有组合数为6种,所以以1,2开头的所有组合数为12种,1,2,3开头的组合数为18种。可以推断第一个数为3,那么通过递归分析可以将原问题转化为1,2,4的所有排列中找第3个(15-3)。2. 代码class Solution {public: string getPe...

2019-12-02 21:44:53 51

原创 LeetCoder_____ 螺旋矩阵 II(59)

1. 思路和之前的螺旋矩阵类似,只不过可以通过数组值是否为0判断是否已经填写过。2. 代码class Solution {public: vector<vector<int>> generateMatrix(int n) { vector<vector<int>> ret(n, vector<int>(n...

2019-12-02 21:41:02 41

原创 LeetCoder_____ 最后一个单词的长度(58)

1. 思路倒序遍历,遇到字符累加,当遇到空格并且累加值不为0的时候就是最后一个单词开始。输出即可2. 代码class Solution {public: int lengthOfLastWord(string s) { int sum = 0; for(int i = s.length() - 1; i >= 0; --i) ...

2019-12-02 21:40:04 35

原创 LeetCoder_____ 插入区间(57)

1. 思路和56题类似,因为题目已经保证了有序,那么我们只需要通过类似于冒泡的思路O(n)的时间复杂度将新区间插入并排序,然后就和56题一样的做法2. 代码class Solution {public: vector<vector<int>> insert(vector<vector<int>>& intervals, ve...

2019-11-28 08:44:38 48

原创 LeetCoder_____ 合并区间(56)

1. 思路这个题目其实只需要先将所有区间按照区间左边界从小到大排序。然后遍历的过程中,判断当前区间和前面是否有重叠,如果有就更新右边界的值,如果没有重叠,就作为一个独立的区间存储起来。我们可以直接在原数组里面进行更新,保证了空间复杂度为O(1)。因为有排序所以时间复杂度为O(nlogn)2. 代码class Solution {public: vector<vector&l...

2019-11-28 08:42:34 35

原创 LeetCoder_____ 跳跃游戏(55)

1. 思路其实我们只需要遍历数组,更新一个最大能跳的距离,如果当前遍历的点超过了最大能跳的距离,说明当前点不可到达,那么最后一个位置同样不能到达。2. 代码class Solution {public: bool canJump(vector<int>& nums) { int maxLength = 0, n = nums.size(); ...

2019-11-28 08:39:37 36

原创 LeetCoder_____ 螺旋矩阵(54)

1. 思路模拟题目,沿着外面一圈一圈的遍历。2. 代码class Solution {public: vector<int> spiralOrder(vector<vector<int>>& matrix) { if(matrix.size() == 0) return {}; int n = matr...

2019-11-28 08:37:48 33

原创 LeetCoder_____ 最大子序列和(53)

1. 思路A这个题目是一个很经典的DP(动态规划)问题,我们定义dp[i]表示以i结尾的子序列最大和为多少,那么递推关系就很明确了,对于一个位置X,要么连上前面X+dp[X-1],要么自己单独成为子序列开始X,所以结果就是两者较大值:dp[x]=max(dp[x−1],0)+xdp[x]=max(dp[x-1],0)+xdp[x]=max(dp[x−1],0)+x时间复杂度O(n),空间复杂...

2019-11-28 08:36:30 34

原创 LeetCoder_____ N皇后 II(52)

1. 思路和N皇后1问题类似,深度搜索,记录个数即可2. 代码class Solution {public: int totalNQueens(int n) { vector<bool> vis1(n), vis2(2*n), vis3(2*n); int ret = 0; dfs(ret, 0, n, vis1, vi...

2019-11-28 08:27:40 30

原创 LeetCoder_____ 按要求补齐数组(330)

1. 题目给定一个已排序的正整数数组 nums,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。示例 1:输入: nums = [1,3], n = 6输出: 1解释:根据 nums 里现有的组合 [1], [3], [1,3],可...

2019-11-25 23:36:18 104

原创 LeetCoder_____ N皇后(51)

1. 思路很经典的深度优先搜索题目了。按照行进行搜索,保证了每行只有一个;用vis1来记录每列是否有旗子,保证每列只有一个左上右下斜线如何记录呢,观察可以发现这条线上的所有坐标x,y的差值是一定的,所以可以用vis2来记录x,y的差值。如果某两个个坐标差值一样表示这两个点在同一斜线上。同理右上左下使用vis3记录x,y两个坐标的和。2. 代码class Solution {p...

2019-11-21 20:07:27 38

原创 LeetCoder_____ Pow(x, n)(50)

1. 思路其实这个题目没有要求精度,仅仅是简单考一个二分快速幂。不过需要注意的是,因为题目中的N可能是负数,在转化为正数的时候需要记住-INT_MAX取反是会超过int范围的。也不能先算幂,最后取倒数,因为会溢出。所以需要在0x80000000 < n && n < 0 这个范围内,就要进行取倒数了。当然也可以直接偷懒用long,防止溢出。2. 代码cla...

2019-11-21 20:02:02 46

原创 LeetCoder_____ 字母异位词分组(49)

1. 思路如何将异位词hash到同一个值是我们需要解决的问题,有很多种方法,排序、算每个字符出现的个数等。这里我们选择排序,异位词经过排序后的是一样的。再利用Map将异位词映射到一个数组中。2. 代码class Solution {public: map<string, vector<string>> mpt; vector<vector&...

2019-11-21 19:57:43 33

原创 LeetCoder_____ 旋转图像(48)

1. 思路模拟题,需要注意题目的要求就是O(1)的时间复杂度。在原来的矩阵上一圈一圈的旋转。通过观察可以得到规律,就是(i,j)位置上的元素为进行如下的转换。(i, j) -> (j, n - 1 - i) -> (n - 1 - 1, n - 1 - j) - > (n - 1- j, i)2. 代码class Solution {public: void...

2019-11-21 19:55:23 28

原创 LeetCoder_____ 摆动排序 II(324)

1. 思路这个题目很容易得到思路:找到中位数,以中位数分为前后两部分在奇数位上插入前部分的数,在偶数位上插入后半部分的数。但是需要注意的是,数组里面重复的数,特别是中位数有重复。例如3,4,4,5。如果我们按照上面的规则任意的插入很有可能出现3,5,4,4这样的结果。显然是不满足题意的。所以在上面的基础上进行补充:找到中位数,以中位数分为小于中位数(前)、等于中位数(中)、大于中位...

2019-11-17 19:54:57 86

原创 数组索引映射(虚拟索引)

1.例题先看一道题,将一个乱序数组排序后,将前面一半翻转,将后面一半翻转,例如:输入:4,1,2,3,5输出:3,2,1,5,4输入:5,2,3,1输出:2,1,5,3其实这个题目很简单,只需要将数组排序后,分为前后两部分,分别翻转即可。void solution(vector<int> &nums){ int n = nums.size();...

2019-11-17 19:13:55 102

原创 Partition算法_求第K大元素

1.二分Partition二分Partition算法是指在O(n)的时间复杂度和O(1)的空间复杂度的情况下将一个数组分为大于某个数和小于某个数的两部分。快速排序其实就是分治+Partition算法。int partition(vector<int> &nums, int begin, int end){ int pivot = nums[begin]; ...

2019-11-17 17:53:06 153

原创 LeetCoder_____ 全排列 II(47)

1. 思路和上一个题目类似,只不过这个题目有重复数字,排列的时候不能有重复了。其实算法思路一样。只不过对于这个题目来说需要先进行排序,在递归选值的过程我们约定对于相邻两个相同的数来说,前面一个数如果没有被选,后面的这个数不能被选。这样就可以剔除掉重复的排列了。2.代码class Solution {public: vector<vector<int>>...

2019-11-13 22:57:15 33

原创 LeetCoder_____ 全排列(46)

1. 思路全排列,标准的dfs回溯题目2.代码class Solution {public: vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>> ret; vector<int> te...

2019-11-13 22:53:57 37

原创 LeetCoder_____ 跳跃游戏 II(45)

1. 思路A被以前做过的一个类似题目限制了思路,用dp,因为是稳定O(n^2)复杂度,所以超时了。改为BFS,也超时了。想了下,BFS可以优化,每个点其实枚举下个可以到达的点,步长不一定是从0开始,因为答案是单调的,也就是说如果到达n需要k步,那么到达比n小的地方需要的步数一定小于等于k。所以可以维护一个已经扩展的最大的值。时间复杂度O(n),空间复杂度O(n)2.代码Aclass S...

2019-11-11 12:52:01 44

原创 LeetCoder_____ 通配符匹配(44)

1. 思路A很显然可以使用dp,令dp[i][j] 表示s,p 字符串前i , j个字符是否可以匹配,而且状态转移方程也很容易推导默认dp[0][0] = true如果s[i] == p[j] || p[j] == ‘?’ 并且 dp[i][j] = true,那么dp[i + 1][j + 1] = true如果p[j] = ‘*’ 并且 dp[i][j] = true,那么 dp[i...

2019-11-09 22:30:03 84

原创 LeetCoder_____ 字符串相乘(43)

1. 思路大数乘法模拟题,其实就是模拟竖式乘法,其实仔细观察竖式乘法可以发现A数第i位乘以B数第j位的结果会累加到最后乘积的第i+j位(个位为第0位),所以只需要遍历i,j并且处理好进位关系就好了。Ans[_[[​i_ii​+j_jj​] += Ai_ii​ + Bj_jj​不过值得的是,字符串的高位是其代表数字的低位,而乘法需要从数字的低位算起, 不断进位。所以我们需要i , j ...

2019-11-09 21:38:14 34

原创 LeetCoder_____ 接雨水(42)

1. 思路A其实观察可以很容易发现,对于每个柱子最后能到达的水面高度取决于左右两边的最高柱子的最小值。所以只需要左右两边扫描一边,得到左边前i个柱子的最高值和右边前i个的最高值。那么对于某个柱子 j,其水面高度为 : min(left_max[j], right_max[j])。时间复杂度O(n),空间复杂度O(n)2.代码Aclass Solution {public: i...

2019-11-06 22:55:49 48

原创 LeetCoder_____ 组合总和 II(40)

1. 思路和前一个题目类似,只不过这里要求每个数只能用一次。所以这里我们需要先将数组排序。然后dfs递归的时候保证不选取重复的数字即可。2.代码class Solution {public: vector<vector<int>> combinationSum2(vector<int>& candidates, int target)...

2019-10-29 11:08:47 31

原创 LeetCoder_____ 组合总数(39)

1. 思路这个题目其实也是标准的dfs,由于每个数可以重复选择,所以每次选择都是从数组的第一个选到最后一个。我看题解有人用dp再做,其实dp在这个题目上并不讨巧。原因是要记录1~target的所有组合,空间开销一定大。当target很大的时候,时间复杂度也很大。2.代码class Solution {public: vector<vector<int>&gt...

2019-10-29 11:06:43 44

原创 LeetCoder_____ 报数(38)

1. 思路这个题目有点绕口,不好理解。其实意思就是告诉你第一项为1,第二项就是对第一项报数,第n项的结果就是对前一项报数。报数的规则如题。这种用递归做代码再简单不过了,由于是尾递归,所以也没有栈开销。2.代码class Solution {public: string countAndSay(int n) { return n == 1 ? "1" : sa...

2019-10-29 11:03:42 30

原创 LeetCoder_____ 解数独(37)

1. 思路深搜dfs,通过vis1, vis2, vis3 分别记录行、列、3x3宫格出线的数字。2.代码class Solution {public: void solveSudoku(vector<vector<char>>& board) { bool vis1[10][10] = {0}, vis2[10][10] = {0...

2019-10-29 11:01:09 47

原创 LeetCoder_____ 有效的数独(36)

1. 思路简单题目,统按需统计即可。2.代码class Solution {public: bool isValidSudoku(vector<vector<char>>& board) { for(int i = 0; i < 9; i ++) { bool vis1[10] = { ...

2019-10-29 10:59:32 35

原创 LeetCoder_____ 在排序数组中查找元素的第一个和最后一个位置(34)

1. 思路标准的二分查找模板,查找左边界和右边界2.代码class Solution {public: vector<int> searchRange(vector<int>& nums, int target) { int l, r; vector<int> ret; l = 0; r =...

2019-10-28 09:24:39 54

原创 【转载】二分查找算法细节详解

文章出处:二分查找算法细节详解思路我相信对很多读者朋友来说,编写二分查找的算法代码属于玄学编程,虽然看起来很简单,就是会出错,要么会漏个等号,要么少加个 1。不要气馁,因为二分查找其实并不简单。看看 Knuth 大佬(发明 KMP 算法的那位)怎么说的:Although the basic idea of binary search is comparatively straightfor...

2019-10-28 09:13:15 62

原创 LeetCoder_____ 搜索旋转排序数组(33)

1. 思路通过二分查找找到翻转点,然后再在两边进行二分查找。2.代码class Solution {public: int search(vector<int>& nums, int target) { int l, r, point = -1, size = nums.size() - 1; l = 0, r = size; ...

2019-10-25 12:17:35 49

原创 LeetCoder_____ 下一个排列(31)

1. 思路这个题目其实就是找规律,多列几组数据就会发现:从右到左找到第一个S[i] < S[i+1]的位置,然后将S[i] ~ S[n]从小到大排序,再将S[i] ~ S[n]中第一个大于S[i]的数和S[i]交换即可。2.代码class Solution {public: void nextPermutation(vector<int>& nums...

2019-10-22 23:59:15 40

原创 LeetCoder_____周赛(159)

1.缀点成线(5230)题目链接: 5230. 缀点成线这个题目做过很多次了,其实考察点就是用斜率判断三个点是否在一个直线上的时候要化除法为乘法,只不过还需要注意的是乘法是否会溢出,不过这个题目给的数据范围保证了不会溢出。class Solution {public: typedef long long ll; bool checkStraightLine(vecto...

2019-10-20 23:39:46 77

提示
确定要删除当前文章?
取消 删除