一、字符串的排列
題幹:
輸入一個字符串,打印出該字符串中字符的所有排列。
你可以以任意順序返回這個字符串數組,但裏面不能有重複元素。
示例:
輸入:s = "abc"
輸出:["abc","acb","bac","bca","cab","cba"]
限制:
1 <= s 的長度 <= 8
題解:
全排列問題可採用遞歸的思路,固定某個位置,求出其他位置的全排列
我們可以通過交換來獲得所有可能的情況。比如第一個位置上的字符,假如 A 和 A 交換,就相當於第一個位置上固定了 A;假如 A 和 B 交換,B來到第一個位置,就相當於第一個位置上固定了 B;假如 A 和 C 交換,C來到第一個位置,就相當於第一個位置上固定了 C。遞歸的過程中都是同理。
此外,因爲可能有字符重複,我們得到的全排列自然也會有重複,那麼我們可以用 set (集合)來去重,並且還可以達到按照字母順序排序的目的。
代碼
class Solution {
public:
set<string> num;
void num_swap(string s,int cnt)
{
if(cnt==s.size()-1)
{
num.insert(s);
return;
}
for(int i=cnt;i<s.size();i++)
{
// for循環和swap的含義:對於“ABC”,
// 第一次'A' 與 'A'交換,字符串爲"ABC", pos爲0, 相當於固定'A'
// 第二次'A' 與 'B'交換,字符串爲"BAC", pos爲0, 相當於固定'B'
// 第三次'A' 與 'C'交換,字符串爲"CBA", pos爲0, 相當於固定'C'
swap(s[cnt],s[i]);
num_swap(s,cnt+1);
swap(s[cnt],s[i]);
// 回溯的原因:比如第二次交換後是"BAC",需要回溯到"ABC"
// 然後進行第三次交換,才能得到"CBA"
}
}
vector<string> permutation(string s) {
num_swap(s,0);
vector<string> ans=vector<string>({num.begin(), num.end()});
return ans;
}
};
二、數組中出現次數超過一半的數字
題幹
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。
你可以假設數組是非空的,並且給定的數組總是存在多數元素。
示例 1:
輸入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
輸出: 2
限制:
1 <= 數組長度 <= 50000
題解
如果有一個數超過數組長度一半,意味着他可以把其他數字全部抵消,海能保證有剩餘,因此,我們設定第一個數爲最終的ans結果,在設置一個cnt次數表示目前該數出現的次數,若果下一個不是該數,並且次數爲0,則更換ans,若果不是該數且次數不爲0,則只減少次數,ans值不變。對數組進行一遍遍歷,即可求出結果。
代碼
class Solution {
public:
int majorityElement(vector<int>& nums) {
int cur=0;
int ans=nums[0];
for(int i=1;i<nums.size();i++)
{
if(nums[i]!=ans)
{
if(cur!=0)
{
cur--;
}
else
{
ans=nums[i];
}
}
else
cur++;
}
return ans;
}
};