目录
一、回文数 9(不是本篇内容,但也是最近写的,也就一起总结啦)
小伙伴们,好啊!从今天起,本篇内容更新leetcode《编程基础0到1》。自己也在边走边学,希望我可以帮助到大家。
一、回文数 9(不是本篇内容,但也是最近写的,也就一起总结啦)
1.正负数怎么判断
直接判断如果是负数就直接false
if (x<0) return false;
2.怎么将数字倒过来,判断是不是回文数
sum肯定要经历三轮*10,所以现在里面乘。这个是我之前错的代码,就是在比原数多了一个数量级。
sum=n%10;
sum*=10;
n/=10;
下面这个是正确的代码。
long long int sum=0;
while(n!=0){
sum=sum*10+n%10;
n/=10;
}
下面来一个正确的完整代码。时间79.3% 内存51.47%
class Solution {
public:
bool isPalindrome(int x) {
if (x<0) return false;
int n=x;
long long int sum=0;
while(n!=0){
sum=sum*10+n%10;
n/=10;
}
return x==sum;
}
};
转化成字符串 时间 79.03% 内存23.41%
class Solution {
public:
bool isPalindrome(int x) {
string s=to_string(x);
return s==string(s.rbegin(),s.rend());
}
};
二、找不同 389
这个sum是int类型,之所以能和string类型相加减,是因为本质上是 ASCII值想加减。
时间 100% 内存 91.78%
class Solution {
public:
char findTheDifference(string s, string t) {
int sum=0;
for(auto i:t) sum+=i;
for(auto i:s) sum-=i;
return sum;
}
};
这个是位运算,其中用到了^异或运算符,即相同为0,不同为1。时间 100% 内存56.27%
class Solution {
public:
char findTheDifference(string s, string t) {
int sum=0;
for(auto i:t) sum^=i;
for(auto i:s) sum^=i;
return sum;
}
};
三、重复的子字符串 459
方法一
这个方法 时间 64.41% 内存 54.67%
bool repeatedSubstringPattern(string s) {
return (s + s).find(s, 1) != s.size();
}
解释:
我们将两个字符串串起来,从索引值1开始查找,查找s,返回的是第一次找到s的索引值。记住这时's+s’已经将索引值0的数删掉了。如果这时候索引值不是原来字符串长度,就说明是true.
举例:
s='ababab',s+s='abababababab',find之后s+s字符串就变为了‘bababababab’。我们会在索引位置 1
找到第一个 "ababab",因此 find
返回 1
。
证明充要性:
正如上面这个例子,s+s变成了‘bababababab’,当查找s时,已经用到下面一个s的首值了,后面肯定是循环的,重复的。如果想不懂,就n个s想加,一直重复下去,就可以啦。
这个代码有点难懂!!!小伙伴们好好品味!!!哈哈哈哈哈哈
方法二
这个方法 时间 64.66% 内存 89.78%
class Solution {
public:
bool repeatedSubstringPattern(string s) {
int n = s.length();
for (int len = 1; len <= n / 2; len++) {
if (n % len == 0) {
bool isRepeated = true;
for (int i = len; i < n; i++) {
if (s[i] != s[i - len]) {
isRepeated = false;
break;
}
}
if (isRepeated) {
return true;
}
}
}
return false;
}
};
解释:
如果s是重复的字符串,必定是长度一半的任何数的倍数。如果不是,直接false。这个可以举例说明。s='ababab',那么6是1,2,3的倍数。如果s='aaa',那3是1的倍数,这都是毋庸置疑的。下面设置一个布尔数默认为true,从1开始到最大重复子串长度(n/2)并于后面所有的相应字符串比较,不相等就false,接着len+1,接着比对,如果到最大长度还找不到就直接false出去,否则就true。
举例:
s='ababab',先判断6是1,2,3的倍数,接着就判断最大子串长度,先是s[1]='b' != s[0]='a',直接退出,接着下一轮循环。s[2]='a' == s[0]='a',所以接着下面匹配,s[3]='b' == s[1]='b',下面在不断匹配,最后判断成功,返回true。
四、交替合并字符串 1768
这个方法 时间 40.39% 内存 85.80%
class Solution {
public:
string mergeAlternately(string word1, string word2) {
string ans;
int i=0,j=0;
int len1 = word1.length(), len2 = word2.length();
while (i < len1 && j < len2) {
ans += word1[i++];
ans += word2[j++];
}
while (i < len1) {
ans += word1[i++];
}
while (j < len2) {
ans += word2[j++];
}
return ans;
}
};
解释:
这个代码很简单,就是当比较这两个字符串长度,先合并,然后比较谁更长,长的追加到后面。
五、找出字符串中第一个匹配的下标 28
这个方法 时间 100% 内存 54.53%
class Solution {
public:
int strStr(string haystack, string needle) {
int ans=haystack.find(needle);
if (ans!=string::npos) return ans;
else return -1;
}
};
解释:
先将找到的索引值设为ans,find函数在找不到指定值得情况下会返回string::npos,如果找到就是true,否则就是false。
这一题和上一题都可以用KMP算法,后面会单独出一期。
六、移动零 283
这个方法 时间 89.53% 内存 22.17%
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int slow=0,fast=0;
int n=nums.size();
while(fast<n){
if(nums[fast]!=0){
swap(nums[slow],nums[fast]);
slow++;
}
fast++;
}
}
};
解释:
双指针做法。现将两个指针设置为0,判断值为快指针,快指针要<n,如果快的不是0就交换,并且慢指针+1,否则只是快指针+1。
七、有效的字母异位词 242
方法一
这个方法 时间 93.37% 内存 49.32%
class Solution {
public:
bool isAnagram(string s, string t) {
if(s.length()!=t.length()) return false;
int charFreq[128]={0};
for(char c:s) charFreq[c]++;
for(char c:t) charFreq[c]--;
for(int i=0;i<128;i++){
if(charFreq[i]!=0) return false;
}
return true;
}
};
解释:
如果两个字符串长度不相等,就直接false。接着,定义字母重复次数,使用的是数组128位(ASCII 0-127),遍历两个字符串,在s中加字母次数,在T中减少次数,最后判断,如果这个次数为0就true,否则就是false。
方法二
这个方法 时间 25.98% 内存 72.78%
class Solution {
public:
bool isAnagram(string s, string t) {
sort(s.begin(),s.end());
sort(t.begin(),t.end());
return s==t;
}
};
这个也不需要解释吧,就是排序,后判断。
八、数组元素积的符号 1822
时间4ms,击败86.91%,内存10.1 MB,击败5.73%
class Solution {
public:
int arraySign(vector<int>& nums) {
int sum=0;
for(auto i:nums){
if(i==0) return 0;
else if(i<0) sum+=1;
}
if(sum%2==0) return 1;
else return -1;
}
};
就是统计正负数个数,不再详解啦。
九、加一 66
时间 100% 内存 71.89%
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int n=digits.size();
for(int i=n-1;i>=0;--i){
if(digits[i]!=9){
++digits[i];
for(int j=i+1;j<n;++j){
digits[j]=0;
}
return digits;
}
}
vector<int>ans(n+1);
ans[0]=1;
return ans;
}
};
解释:
从最右边的数开始循环,如果这个是不是9,就直接在这个数基础上+1,然后返回。如果是9,就一直遍寻到找到不是9的那个数,然后在这个数+1,然后后面的数置0。最后,如果全都是9的话,直接在设置一个ans,比原来的多一位数,使最前面置1,后面全是0。
十、判断能否形成等差数列 1502
这个方法 时间 70.73% 内存 82.93%
class Solution {
public:
bool canMakeArithmeticProgression(vector<int>& arr) {
sort(arr.begin(),arr.end());
int cha=arr[1]-arr[0];
for(int i=0;i<arr.size()-1;i++){
if(arr[i+1]-arr[i]!=cha) return false;
}
return true;
}
};
排序并判断。这题比较简单就不详细解答了。
十一、单调数列 896
方法一
时间 5.17% 内存 55.66%
class Solution {
public:
bool isMonotonic(vector<int>& nums) {
bool decrease=true;
bool increase=true;
for(int i=0;i<nums.size()-1;i++){
if(nums[i+1]>nums[i]) decrease=false;
else if(nums[i+1]<nums[i]) increase=false;
}
return decrease||increase;
}
};
解释:
定义两个布尔型一个升一个降,遍历数组,如果后一个大于前一个,就不是递减。后一个小于前一个,就不是递增。最后用或运算符。
方法二:
时间 43.08% 内存 24.62%
class Solution {
public:
bool isMonotonic(vector<int>& nums) {
return is_sorted(nums.begin(),nums.end())||is_sorted(nums.rbegin(),nums.rend());
}
};
这个使用的c++自带的函数,遍历两次数组,分别判断其是否为单调递增或单调递减。
十二、最后一个单词的长度 58
方法一
时间 44.36% 内存 5.1%
这个方法是我刚开始想到的方法,效率不高,但是只能想到这个。
class Solution {
public:
int lengthOfLastWord(string s) {
s+=' ';
vector<int>counts;
int count=0;
for(int i=0;i<s.size();i++){
if(s[i]!=' '){
count++;
}
else {
if(count!=0){
counts.push_back(count);
}
count=0;
}
}
int n=counts.size();
return counts[n-1];
}
};
解释:
第一句话在s后面加个字符串就是截断最后一个字符串。然后将每个字符串长度保存在数组里,取最后一个数组就可以啦。
方法二
时间 100% 内存 73.24%
这个方法是看了题解,由反向遍历想到的,比官方解答效率高。
class Solution {
public:
int lengthOfLastWord(string s) {
int count=0;
int n=s.size();
for(int i=n-1;i>=0;i--){
if(s[i]!=' ') {
count++;
}
else if(count>0) break;
}
return count;
}
};
解释:
就是一个if语句,如果不是空格,就+1,是空格的时候用下一个语句,break出去。最后返回。
十三、罗马数字转整数 13
这一题拿到的时候真的没有思路,只能想到用很多if语句。但是最后也没有写,感觉太麻烦了。在官网找题解的时候,也是有点震惊的,我以为c++的类是摆设,因为我从来没用过类,都是用的类内函数,类外函数依然可以实现。但是这次实实在在用类了,第一次用到,记录一下,哈哈哈哈哈
官网题解
时间 81.67% 内存 37.59%
class Solution {
private:
unordered_map<char,int>symbolValues={
{'I',1},
{'V',5},
{'X',10},
{'L',50},
{'C',100},
{'D',500},
{'M',1000},
};
public:
int romanToInt(string s) {
int ans=0;
int n=s.length();
for(int i=0;i<n;++i){
int value=symbolValues[s[i]];
if(i<n-1&&value<symbolValues[s[i+1]]){
ans-=value;
}
else{
ans+=value;
}
}
return ans;
}
};
解释:
这个代码的核心,是前面字母对应的值要比后面的小,才是用减法。我是没想到(hahaha)
private 就是用一个map容器,将对应的字母和值记录下来。然后如果前面字母对应的值要比后面的小,用减法。否则用加法。
十四、棒球比赛 682
方法一
class Solution {
public:
int calPoints(vector<string>& operations) {
vector<int>ans;
for(int i=0;i<operations.size();i++){
if(operations[i]=="C"){
if(!ans.empty()){
ans.pop_back();
}
}
else if(operations[i]=="D"){
if(!ans.empty()){
ans.push_back(ans.back()*2);
}
}
else if(operations[i]=="+"){
if(ans.size()>=2){
ans.push_back(ans[ans.size()-1]+ans[ans.size()-2]);
}
}
else{
ans.push_back(stoi(operations[i]));
}
}
int totalScore=0;
for(int score:ans){
totalScore+=score;
}
return totalScore;
}
};
解释:
stoi()函数——将数字字符转化为为int类型输出。
如果是数字的话直接转化为int类型加入,如果是‘C’,判断数组不是空的然后删掉最后一个数字,如果是‘D’,判断数组不是空的然后加入最后一个数字的二倍,如果是‘+’,判断前面要有两个数,再将他们想加,加入数组。最后算总输出。
十五、转化成小写字母 709
方法一
class Solution {
public:
string toLowerCase(string s) {
transform(s.begin(),s.end(),s.begin(),::tolower);
return s;
}
};
这个方法是网上找的函数,大家可以去搜一搜。
方法二
class Solution {
public:
string toLowerCase(string s) {
for(int i=0;i<s.size();i++){
if(s[i]>='A'&&s[i]<='Z'){
s[i]+=32;
}
}
return s;
}
};
解释:
这个方法利用了在ASCII中,对应的小写字母比大写字母多32。
方法三
class Solution {
public:
string toLowerCase(string s) {
for(char &ch:s){
ch=tolower(ch);
}
return s;
}
};
这个就是将遍历字符串,将大写转为小写。利用了tolower函数。
十六、最富有客户的资产总量 1672
方法一
class Solution {
public:
int maximumWealth(vector<vector<int>>& accounts) {
int maxWealth=INT_MIN;
for(auto &account:accounts){
maxWealth=max(maxWealth,accumulate(account.begin(),account.end(),0));
}
return maxWealth;
}
};
解释:
int sum = accumulate(account.begin() , account.end() , 0);
accumulate第一个参数为vector二维数组的开始,第二个是结尾,第三个参数是sum的初始值。
INT_MAX = 2^31-1,INT_MIN= -2^31
方法二
class Solution {
public:
int maximumWealth(vector<vector<int>>& accounts) {
vector<int>counts;
int sum=0;
for(int i=0;i<accounts.size();i++){
for(int j=0;j<accounts[0].size();j++){
sum+=accounts[i][j];
counts.push_back(sum);
}
sum=0;
}
return *max_element(counts.begin(),counts.end());;
}
};
解释:
这个先将每个人的总资产算出来,保存到数组里,然后再返回最大值。
十七、机器人能否返回原点 657
方法一
class Solution {
public:
bool judgeCircle(string moves) {
int x = 0, y = 0;
for (const auto& move: moves) {
if (move == 'U') {
y--;
}
else if (move == 'D') {
y++;
}
else if (move == 'L') {
x--;
}
else if (move == 'R') {
x++;
}
}
return x == 0 && y == 0;
}
};
解释:
这个方法就是利用了上下、左右是对立面。只要对立面方向走的步数一样就可以回到原点。
方法二
class Solution {
public:
bool judgeCircle(string moves) {
return count(moves.begin(),moves.end(),'U') == count(moves.begin(),moves.end(),'D')
&& count(moves.begin(),moves.end(),'L') == count(moves.begin(),moves.end(),'R');
}
};
解释:
count(moves.begin() , moves.end() , 'U')
count函数第一个就是计算数组开始值,第二个参数是结束值,第三个是要搜索的值。
本质还是和方法一一样,不做赘述。
十八、矩阵对角线元素的和 1572
方法一
第一遍自己写的,我以为中间会加两次,就奇偶分开写了,在积后面减去中间的数,不对。下面是改正版。
class Solution {
public:
int diagonalSum(vector<vector<int>>& mat) {
int sum=0;
int n=mat.size()-1;
for(int i=0;i<mat.size();i++){
if(mat.size()%2==1){
for(int j=0;j<mat.size();j++){
if(j==i||j==n-i){
sum+=mat[i][j];
}
}
}
else{
for(int j=0;j<mat.size();j++){
if(j==i||j==n-i){
sum+=mat[i][j];
}
}
}
}
return sum;
}
};
解释:
这个很简单,抓住对角线方程就可以。y=x;y=n-x这两个方程的应用。
方法二
这个来个简化版的
class Solution {
public:
int diagonalSum(vector<vector<int>>& mat) {
int sum=0;
int n=mat.size()-1;
for(int i=0;i<mat.size();i++){
for(int j=0;j<mat.size();j++){
if(j==i||j==n-i){
sum+=mat[i][j];
}
}
}
return sum;
}
};
方法三
class Solution {
public:
int diagonalSum(vector<vector<int>>& mat) {
int n = mat.size(), sum = 0, mid = n / 2;
for (int i = 0; i < n; ++i) {
sum += mat[i][i] + mat[i][n - 1 - i];
}
return sum - mat[mid][mid] * (n & 1);
}
};
解释:
这个方法和上面两个方法差不多。但是他奇数矩阵中间算了两次,巧妙的用了按位与运算。n如果是奇数,就减,否则不减。
十九、矩阵置零 73
方法一
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
vector<int> row(m), col(n);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!matrix[i][j]) {
row[i] = col[j] = true;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (row[i] || col[j]) {
matrix[i][j] = 0;
}
}
}
}
};
解释:
就是遍寻数组,然后将是0的分别标记在一维数组里,然后再遍寻一遍数组,将其置0。
官网题解的方法二时间复杂度和空间复杂度都比方法一差,还不好理解。所以,我们就不做解释了。
二十、在区间范围内统计奇数数目 1523
方法一
时间868,啊哈哈哈,自己写的(苦涩的笑容)
class Solution {
public:
int countOdds(int low, int high) {
int count=0;
if(low%2==1){
for(int i=low;i<high+1;){
i+=2;
count++;
}
}
else{
for(int i=low+1;i<high+1;){
i+=2;
count++;
}
}
return count;
}
};
这个题一定要注意开始的数字是奇数还是偶数,奇数比偶数多一个。
方法二
class Solution {
public:
int countOdds(int low, int high) {
if(high%2==0 && low%2==0) return (high-low) / 2;
else return (high-low) / 2 + 1;
}
};
哎,一样的思路,别人写的就是有简短,效率又高。
二十一、去掉最低工资和最高工资后的工资平均值
class Solution {
public:
double average(vector<int>& salary) {
double maxValue = *max_element(salary.begin(), salary.end());
double minValue = *min_element(salary.begin(), salary.end());
double sum = accumulate(salary.begin(), salary.end(), - maxValue - minValue);
return sum / int(salary.size() - 2);
}
};
这个方法函数详解上面有,思路也很简单,就不赘述啦。
二十二、三角形的最大周长 976
方法一
class Solution {
public:
int largestPerimeter(vector<int>& nums) {
int n=nums.size();
sort(nums.begin(),nums.end());
for(int i=n-1;i>=2;--i){
if(nums[i]<nums[i-1]+nums[i-2]) return nums[i]+nums[i-1]+nums[i-2];
}
return 0;
}
};
主要突破点:
已经排序好了,只要后两个大于这个就可以构成三角形。
二十三、柠檬水找零 860
方法一
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five=0,ten=0;
for(auto b:bills){
if(b==5) five++;
else if(b==10) ten++,five--;
else if(ten) five--,ten--;
else five-=3;
if(five<0) return false;
}
return true;
}
};
主要突破点:
另外找两个数,用于存储5元和10元的,并且付20元时,先花费10+5元的。
二十三、二进制求和 67
方法一
class Solution {
public:
string addBinary(string a, string b) {
string sum;
int t=0;
for(int i=a.size()-1,j=b.size()-1;i>=0||j>=0;--i,--j){
if(i>=0) t+=a[i]-'0';
if(j>=0) t+=b[j]-'0';
sum.push_back((t%2)+'0');
t/=2;
}
if(t) sum.push_back(1+'0');
reverse(sum.begin(),sum.end());
return sum;
}
};
解释:
这个a[i]-'0'是将a[i]转化为整数,同理下面的-‘0’’也是。但是这个两个不一样。
这是因为字符 '0' 到 '9' 是 ASCII 码表中连续的字符,因此字符减去 '0' 会得到它所代表的数字。例如,字符 '1' 减去 '0' 会得到整数 1,字符 '2' 减去 '0' 会得到整数 2,以此类推。
在这段代码中,
a[i]-'0'
是将字符型的数字转换成了整数型的数字,以便进行二进制加法运算。同样地,b[j]-'0'
也是将字符型的数字转换成了整数型的数字。在二进制加法中,
(t%2)+'0'
和(t%2)-'0'
的结果是不同的。当t%2
为 0 时,(t%2)+'0'
的结果是 '0',而(t%2)-'0'
的结果是非法字符,因为不能将字符减去数字。所以,这个表达式不能简单地用-‘0’
替换。
方法二
class Solution {
public:
string addBinary(string a, string b) {
int al=a.size();
int bl=b.size();
while(al<bl){
a='0'+a;++al;
}
while(al>bl){
b='0'+b;++bl;
}
for(int j=a.size()-1;j>0;--j){
a[j]=a[j]-'0'+b[j];
if(a[j]>='2'){
a[j]=(a[j]-'0')%2+'0';
a[j-1]=1+a[j-1];
}
}
a[0]=a[0]-'0'+b[0];
if(a[0]>='2'){
a[0]=(a[0]-'0')%2+'0';
a='1'+a;
}
return a;
}
};
这个方法就是在短的前面补0,然后进行加减,如果>=2,就留下余数,最后还要判断【0】的数。
二十四、缀点成线 1232
class Solution {
public:
bool checkStraightLine(vector<vector<int>>& coordinates) {
if (coordinates.size() <= 2) {
return true;
}
int x0 = coordinates[0][0];
int y0 = coordinates[0][1];
int x1 = coordinates[1][0];
int y1 = coordinates[1][1];
for (int i = 2; i < coordinates.size(); i++) {
int x = coordinates[i][0];
int y = coordinates[i][1];
if ((y1 - y0) * (x - x0) != (y - y0) * (x1 - x0)) {
return false;
}
}
return true;
}
};
主要突破口:
如果有一般式的话,太麻烦了,要判断x的变化量等不等于0,用两点式就可以避免。
二十五、找出并字棋的获胜者 1275
class Solution {
public:
string tictactoe(vector<vector<int>>& moves) {
int len = moves.size();
vector<vector<int>> ans(4, vector<int>(3, 0));
if (len <= 4) return "Pending";
for (int i = (len + 1) % 2; i < len; i += 2) {
for (int j = 0; j < 2; j++) {
ans[j][moves[i][j]] += 1;
}
if (moves[i][0] == moves[i][1]) {
ans[2][0] += 1;
}
if (moves[i][0] + moves[i][1] == 2) {
ans[3][0] += 1;
}
}
for (const auto& i : ans) {
for (int j : i) {
if (j == 3 && len % 2 == 1) {
return "A";
}
if (j == 3 && len % 2 == 0) {
return "B";
}
}
}
if (len == 9) {
return "Draw";
} else {
return "Pending";
}
}
};
解释:
-
首先,代码检查moves数组的长度是否小于等于4,如果是,则返回"Pending",表示游戏尚未结束。
-
然后,代码创建一个4x3的二维整数数组ans,用于记录井字棋游戏中各个玩家的得分情况。
-
接下来,代码通过两个嵌套的循环遍历moves数组。外层循环从索引为(len+1)%2的位置开始,每次递增2,直到索引达到len-1。内层循环固定为两次迭代。
-
在内层循环中,代码根据moves数组中的值更新ans数组。具体地,对于每个内层循环迭代,代码将ans数组的第一维和第二维分别与moves数组的值进行比较,并根据比较结果更新ans数组对应位置的计数器。
-
接着,代码检查当前行的两个元素是否相等,如果相等,则将ans数组的第三维第一列对应的计数器加1。
-
然后,代码检查当前行的两个元素的和是否为2,如果是,则将ans数组的第三维第一列对应的计数器加1。
-
在完成对moves数组的遍历后,代码通过两个嵌套的循环遍历ans数组。外层循环遍历ans数组的每一行,内层循环遍历每一行的每个元素。
-
在内层循环中,代码根据ans数组的元素值进行逻辑判断。如果某个元素的值为3且moves数组的长度为奇数,则返回"A",表示玩家A获胜。如果某个元素的值为3且moves数组的长度为偶数,则返回"B",表示玩家B获胜。
-
如果代码执行到这里,说明moves数组的长度为9,即井字棋游戏已经结束。此时,代码返回"Draw",表示游戏平局。
-
如果代码执行到最后一行,说明moves数组的长度既不是4以下,也不是9,则返回"Pending",表示游戏尚未结束。
两个for循环这个虽然后文好像没用到,但是还是很有用的
在这段代码中,通过内层的for循环遍历当前行的两个元素moves[i][j],并将ans[j][moves[i][j]]的值加1,表示对应位置的元素出现次数加1。
由于后续的判断依赖于对ans数组的访问,如果去掉这段代码,将无法正确统计和判断"X"和"O"的出现情况,从而导致函数返回的结果不正确。
因此,保留这段代码是必要的,以确保正确地统计每一行中每个元素的出现次数,并进行后续的判断和处理。
二十六、困于环中的机器人 1041
class Solution {
public:
bool isRobotBounded(string instructions) {
vector<vector<int>> direc {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int direcIndex = 0;
int x = 0, y = 0;
for (char instruction : instructions) {
if (instruction == 'G') {
x += direc[direcIndex][0];
y += direc[direcIndex][1];
} else if (instruction == 'L') {
direcIndex += 3;
direcIndex %= 4;
} else {
direcIndex++;
direcIndex %= 4;
}
}
return direcIndex != 0 || (x == 0 && y == 0);
}
};
解释:
x,y用于统计位置,direcIndex用于统计方向,最后如果方向只转了一圈或者原位置不动就是真的。