练习记录而已,以及经常拷打ai(
1 version1:暴力解法,但是$O(n^2)$的复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution {public :vector<int > twoSum (vector<int >& nums, int target) {int n=nums.size (); vector<int >newnums (2 );for (int i=0 ;i<n;i++){for (int j=i+1 ;j<n;j++){if (nums[i]+nums[j]==target){ newnums[0 ]=i; newnums[1 ]=j;return newnums; } } }return {}; } };
哈希表的话等我再学习一段时间再说(
7 反转逻辑是对的但是被溢出卡了一会
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <vector> #include <cmath> #include <climits> using namespace std;class Solution {public : int reverse (int x) { if (x == INT_MIN) return 0 ; int absvalue = abs (x); long long sum = 0 ; while (absvalue) { sum = sum * 10 + absvalue % 10 ; absvalue /= 10 ; } if (x > 0 ) { if (sum > INT_MAX) return 0 ; return (int )sum; } else { if (-sum < INT_MIN) return 0 ; return (int )(-sum); } } };
27 终于没有大败而归了(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public : int removeElement (vector<int >& nums, int val) { int n=nums.size (); int k=0 ; int le=0 ,ri=n-1 ; for (le=0 ;le<=ri;){ if (nums[le]!=val) le++; else { swap (nums[le],nums[ri]); ri--; k++; } } return (n-k); } };
28 依旧失败,问题在于考虑成功的概率和失败的概率比较来看,失败的概率更高,故return持续设置为-1较为合理,而唯一成功的情况进行逻辑运算即可。(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public :int strStr (string haystack, string needle) {int n=haystack.size (),m=needle.size ();for (int i=0 ;i<=n-m;i++){int j=0 ;while (j<m && haystack[i+j]==needle[j]) j++;if (j==m)return i; }return -1 ; } };
暴力解法,从haystack开始比较的解法,逐个比对。
给出的kmp算法没怎么看懂(
66 vetcor的库还是不太熟悉,不知道该怎么下手了(((
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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]+=1 ;return digits; } digits[i]=0 ; } digits.insert (digits.begin (),1 );return digits; } };
67 奋力思考,然后写废了,我是废物喵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 class Solution {public :string addBinary (string a, string b) {int la = a.size (),lb = b.size ();for (int i = 0 ; i < la; i++) { a[i] -= '0' ; }for (int i = 0 ; i < lb; i++) { b[i] -= '0' ; } string str;int index = 1 ;int carry = 0 ;int bit = 0 ;int sum = 0 ;for (int i = 1 ; i < min (la, lb)+1 ; i++){ sum = a[la-i] + b[lb-i] + carry; bit = sum % 2 ; carry = sum / 2 ; str.insert (str.begin (), (bit+'0' )); index++; }while (index <= la) { sum = a[la-index] + carry; bit = sum % 2 ; carry = sum / 2 ; str.insert (str.begin (), (bit+'0' )); index++; }while (index <= lb) { sum = b[lb-index] + carry; bit = sum % 2 ; carry = sum / 2 ; str.insert (str.begin (), (bit+'0' )); index++; } if (carry == 1 ){ str.insert (str.begin (), (carry+'0' )); }return str; } };
242 错误示范( 以为能用异或解决这种问题,但是对于形如“aa”和’bb’的测试用例自身异或计算后为0了😭。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public :bool isAnagram (string s, string t) {if (s.size ()!=t.size ())return false ;char res= 0 ;for (char c:s)res^=c;for (char c:t)res^=c;if (!res)return true ;else return false ; } };
使用散列表计数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {public :bool isAnagram (string s, string t) {if (s.size ()!=t.size ())return false ; int cnt[26 ]={0 };for (char c:s)cnt[c-'a' ]++;for (char c:t)cnt[c-'a' ]--;for (int i=0 ;i<26 ;i++){if (cnt[i]!=0 )return false ; }return true ; } };
283 双指针,提取不为0的排序剩下全部置为0即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {public :void moveZeroes (vector<int >& nums) {int n=nums.size ();int non=0 ;for (int i=0 ;i<n;i++){if (nums[i]!=0 ) nums[non++]=nums[i]; }while (non<n) { nums[non++]=0 ; } } };
389 错误示范(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution {public :char findTheDifference (string s, string t) {int n=s.size ();for (int i=0 ;i<n+1 ;i++){int j=0 ;while (t[i]!=s[j]&&j<n)j++;if (j==n) return t[i]; } } };
version1 :异或
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public :char findTheDifference (string s, string t) {char res = 0 ;for (char c : s) res ^= c;for (char c : t) res ^= c;return res; } };
for(char c : s) 是 C++11 引入的基于范围的for循环 语法,用于简化对容器(如 std::string_、数组、_vector 等)的遍历。它会依次将容器中的每个元素赋值给循环变量 _c_,直到遍历结束。(来自being)
寒假其实看过Tosding关于异或的一点东西,但是实际使用还是非常陌生(((
version2:求和
1 2 3 4 5 6 7 8 9 10 11 char findTheDifference (string s, string t) {int sum = 0 ;for (char c : t) sum += c;for (char c : s) sum -= c;return (char )sum; }
利用ascii码进行加减运算绕过逐个字符比较
总结两个版本总体的思想是通过把字符串的形象字符抽离为机器码进行加和总体运算
459 暴力解法完善版本(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution {public :bool repeatedSubstringPattern (string s) {int n=s.size ();for (int len =1 ;len<=n/2 ;len++){if (n%len!=0 )continue ; string sample=s.substr (0 ,len); string word;int repeat =n/len;for (int j=0 ;j<repeat;j++){ word+=sample; }if (word==s) return true ; }return false ; } };
这次的暴力解法对子串的构造没有利用好string的库,试图自己构造子串但是又没写好(((思路上是一样的但是具体实现还是出现了问题。 不过记得设置return false而不是空悬,这也是进步吗?(
官方最优解
1 2 3 4 5 6 class Solution {public : bool repeatedSubstringPattern (string s) { return (s + s).find (s, 1 ) != s.size (); } };
非常巧妙的算法,利用find从拼接自身一次的s进行寻找s。
1588 超绝不经意$0(n^3)$复杂度(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution {public : int sumOddLengthSubarrays (vector<int >& arr) { int n = arr.size (); int total = 0 ; for (int i = 0 ; i < n; ++i) { for (int len = 1 ; i + len <= n; len += 2 ) { for (int j = i; j < i + len; ++j) { total += arr[j]; } } } return total; } };
神秘的数学方法:计算数组每个元素的出现次数再求和
1 2 3 4 5 6 7 8 9 10 11 class Solution {public : int sumOddLengthSubarrays (vector<int >& arr) { int n = arr.size (); int total = 0 ; for (int i = 0 ; i < n; ++i) { total += arr[i] * ((i + 1 ) * (n - i) + 1 ) / 2 ; } return total; } };
1768 字符串拼接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution {public :string mergeAlternately (string word1, string word2) { string word;int num1=word1. size (),num2=word2. size ();int i=0 ,j=0 ;while (i<num1&&j<num2){ word+=word1[i++]; word+=word2[j++]; }while (i<num1)word+=word1[i++];while (j<num2)word+=word2[j++];return word; } };
整体来看主要是先对齐再考虑长度不同的情况,以及指针不一定真的是指针类型(之前有点局限了