刷题第六天

1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次

方法1:利用和 计算1-1000的和,然后计算数组的和,差值是出现两次元素的值

方法二;利用异或先把1-1000异或,然后和数组里面的所有元素进行异或

int num(vector<int> array)
{  
  int re = 0;  
  for(int i=1;i<=1000;i++)  
    re ^= i;  
  for(int i=0;i<=1000;i++)  
    res ^= array[i];  
  return res;
}

567. 字符串的排列

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。

换句话说,第一个字符串的排列之一是第二个字符串的子串。

示例1:

输入: s1 = “ab” s2 = “eidbaooo”
输出: True
解释: s2 包含 s1 的排列之一 (“ba”).

示例2:

输入: s1= “ab” s2 = “eidboaoo”
输出: False

//思路:滑动窗口法,利用一个map数组统计字符串s1字母出现的次数,当右指针的长度大于左指针的长度时,s2包含·s1;

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
       unordered_map<char,int> mp;
       for(int i=0;i<s1.size();i++){
           mp[s1[i]]++;
       }
       int l=0;//定义左窗口
       int r=0;//定义右窗口
       while(r<s2.size()){
           char temp=s2[r];
           r++;//更新右窗口值
           mp[temp]--;//判断temp字符是否出现在s1中,或者次数出现是否满足要求
           while(l<r&&mp[temp]<0){//此时不满足连续的要求,我们需要把左窗口值更新到上一个temp的位置+1;
               mp[s2[l]]++;
               l++;
           }
           if(r-l==s1.size()){//右窗口减去左窗口==s1的长度,找到连续位置
             return true;
           }
       }
       return false;
    }
};

791. 自定义字符串排序

字符串S和 T 只包含小写字符。在S中,所有字符只会出现一次。

S 已经根据某种规则进行了排序。我们要根据S中的字符顺序对T进行排序。更具体地说,如果S中x在y之前出现,那么返回的字符串中x也应出现在y之前。

返回任意一种符合条件的字符串T。

示例:
输入:
S = “cba”
T = “abcd”
输出: “cbad”
解释:
S中出现了字符 “a”, “b”, “c”, 所以 “a”, “b”, “c” 的顺序应该是 “c”, “b”, “a”.
由于 “d” 没有在S中出现, 它可以放在T的任意位置. “dcba”, “cdba”, “cbda” 都是合法的输出。
注意:

S的最大长度为26,其中没有重复的字符。
T的最大长度为200。
S和T只包含小写字符。

//复杂写法
class Solution {
public:
    string customSortString(string s, string t) {
     unordered_map<char,int> mp;
     unordered_map<char,int> res;
     for(int i=0;i<s.size();i++){
         mp[s[i]]++;
     }
     for(int i=0;i<t.size();i++){
         res[t[i]]++;
     }
     string s1;
     for(int i=0;i<t.size();i++){
         if(mp.find(t[i])==mp.end()){
             s1+=t[i];
         }
     }
  
     string s2;
     for(int i=0;i<s.size();i++){
         if(res.find(s[i])!=res.end()){
             for(int j=0;j<res[s[i]];j++){
                 s2+=s[i];
             }
         }
     }
     return s2+s1;
    }
};
//lambda表达式
class Solution {
public:
    string customSortString(string s, string t) {
     unordered_map<char,int> mp;
      for(int i=0;i<s.size();i++){
          mp[s[i]]=i;
      }
      auto cmp=[&]( auto &a,auto &b){
          return mp[a]<mp[b];
      };
      sort(t.begin(),t.end(),cmp);
      return t;
    }
};

#394. 跳石头

题目描述
​ 一年一度的“跳石头”比赛又要开始了!

​ 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。

​ 为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能移走起点和终点的岩石)。

输入
​ 第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。保证 L≥1 且 N≥M≥0。

接下来 N 行,每行一个整数,第 i 行的整数 Di(0<Di<L), 表示第 i 块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。

输出
​ 一个整数,即最短跳跃距离的最大值。

样例输入
25 5 2
2
11
14
17
21
样例输出
4
样例说明
​ 将与起点距离为 2 和 14 的两个岩石移走后,最短的跳跃距离为 4 (从与起点距离 17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点)。

数据规模与约定
​ 时间限制:1 s

​ 内存限制:256 M

​ 100% 的数据保证 0≤M≤N≤50,000,1≤L≤1,000,000,000

#include<iostream>
using namespace std;
int l, r;
int nums[50005];
int L, N, M;
int bs(int mid,int m) {
	int res = 0;
	int temp = nums[0];
	for (int i = 1; i <= N + 1; i++) {
		if (mid > nums[i] - temp) {
			res++;
		}
		else {
			temp = nums[i];
		}
	}
	return res;

}
int main() {
	
	cin >> L >> N >> M;
	l = 0;
	r = L;
	for (int i = 1; i <=N; i++) {
		cin >> nums[i];
	}
	nums[N + 1] = L;
	while (l != r) {
		int mid = (l + r + 1) / 2;
		if (bs(mid,N) <= M) {
			l = mid;
		}
		else {
			r = mid - 1;
		}
	}
	cout << l << endl;
}

#389. 暴躁的程序猿

题目描述
​ 某公司的程序猿每天都很暴躁,因为他们每个人都认为其他程序猿和自己风格不同,无法一同工作,当他们的工位的编号距离太近时,他们可能会发生语言甚至肢体冲突,为了尽量避免这种情况发生,现在公司打算重新安排工位,因为有些关系户的工位是固定的,现在只有一部分工位空了出来,现在有 N 个程序猿需要分配在 M 个工位中,第 i 个工位的编号为 Xi,工位编号各不相同,现在要求距离最近的两个程序猿之间的距离最大,求这个最大距离是多少。Xi 和 Xj 工位之间距离为|Xi−Xj|。

输入
​ 输入共 M+1 行。

​ 第一行两个整数 M,N。(1≤N≤M≤100,000)
​ 接下来 M 行,每行一个数,表示剩余的工位的编号。

输出
​ 输出距离最近的两个程序猿之间的最大距离。

样例输入
5 3
1
2
8
4
9
样例输出
3
数据规模与约定
​ 时间限制:1 s

​ 内存限制:256 M

​ 100% 的数据保证 1≤N≤M≤100,000,1≤Xi≤1,000,000,000


```cpp
#include<iostream>
using namespace std;
#include<algorithm>
int n, m, num[1000005];
int func(int mid) {
	int a = 1;
	int pre = num[0];
	for (int i = 1; i < n; i++) {
		if (num[i] - pre >= mid) {
			a++;
			pre = num[i];
		}
		
	}
	return a;
}
int bs() {
	int l = 1;
	int r = num[n - 1] - num[0]; 
	while (l != r) {
		int mid = (l + r + 1) / 2;
		int s = func(mid);
		if (s >= m) {
			l = mid;
		}
		else {
			r = mid - 1;
		}
	}
	return l;
}
int main() {
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> num[i];
	}
	sort(num, num + n);
	cout << bs() << endl;
}

## 953. 验证外星语词典
某种外星语也使用英文小写字母,但可能顺序 order 不同。字母表的顺序(order)是一些小写字母的排列。

给定一组用外星语书写的单词 words,以及其字母表的顺序 order,只有当给定的单词在这种外星语中按字典序排列时,返回 true;否则,返回 false。

 

示例 1:

输入:words = ["hello","leetcode"], order = "hlabcdefgijkmnopqrstuvwxyz"
输出:true
解释:在该语言的字母表中,'h' 位于 'l' 之前,所以单词序列是按字典序排列的。
示例 2:

输入:words = ["word","world","row"], order = "worldabcefghijkmnpqstuvxyz"
输出:false
解释:在该语言的字母表中,'d' 位于 'l' 之后,那么 words[0] > words[1],因此单词序列不是按字典序排列的。
示例 3:

输入:words = ["apple","app"], order = "abcdefghijklmnopqrstuvwxyz"
输出:false
解释:当前三个字符 "app" 匹配时,第二个字符串相对短一些,然后根据词典编纂规则 "apple" > "app",因为 'l' > '∅',其中 '∅' 是空白字符,定义为比任何其他字符都小(更多信息)。


```cpp
class Solution {
public:
    bool isAlienSorted(vector<string>& words, string order) {
        unordered_map<char,int> mp;
        for(int i=0;i<order.size();i++){
            mp[order[i]]=i;
        }
        int n=words.size();
        for(int i=0;i<n-1;i++){
            int flag=0;//标志点,用于标志当前两个元素是否是字典序顺序
            for(int j=0;j<min(words[i].size(),words[i+1].size());j++){
                if(mp[words[i][j]]<mp[words[i+1][j]]){
                   flag=1;
                    break;
                }
                else if(mp[words[i][j]]>mp[words[i+1][j]]){
                    return false;
                }
               
            }
            if(flag==0){//不是字典序顺序,判断前后两个单词的大小
                if(words[i].size()>words[i+1].size()){
                 return false;
            }
            }
             
        }
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值