给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i]
的值是 nums[i] 右侧小于 nums[i]
的元素的数量。
示例:
输入: [5,2,6,1] 输出: [2,1,1,0] 解释: 5 的右侧有 2 个更小的元素 (2 和 1). 2 的右侧仅有 1 个更小的元素 (1). 6 的右侧有 1 个更小的元素 (1). 1 的右侧有 0 个更小的元素.
1 | import bisect |
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i]
的值是 nums[i] 右侧小于 nums[i]
的元素的数量。
示例:
输入: [5,2,6,1] 输出: [2,1,1,0] 解释: 5 的右侧有 2 个更小的元素 (2 和 1). 2 的右侧仅有 1 个更小的元素 (1). 6 的右侧有 1 个更小的元素 (1). 1 的右侧有 0 个更小的元素.
1 | import bisect |
Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
Example 1:
Input: "bcabc" Output: "abc"
Example 2:
Input: "cbacdcbc" Output: "acdb"
1 | class Solution: |
a clear solution:
1 | class Solution: |
在Linux 或者 UNIX 操作系统中在系统的引导的时候会开启很多服务,这些服务就叫作守护进程 。
守护进程是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件 。
由于在 Linux 中,每 个系统与用户进行交流的界面称为终端,每 个从此终端运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关
闭时,相应的进程 会自动关闭 ,但是守护进程却能够突破这种限制,它从被执行时开始运转,直到整个系统关闭时才退出 ,如果想让某个进程不因为用户或终端或其他地变化而受到关闭
,那么就必须把这个进程变成一个守护进程。
一个简单的守护进程的步骤如下所述:
1 | #include <stdio.h> |
给定一个字符串数组 words,找到 length(word[i]) * length(word[j])
的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。
示例 1:
输入: ["abcw","baz","foo","bar","xtfn","abcdef"] 输出: 16 解释: 这两个单词为 "abcw", "xtfn"。
示例 2:
输入: ["a","ab","abc","d","cd","bcd","abcd"] 输出: 4 解释: 这两个单词为 "ab", "cd"。
示例 3:
输入: ["a","aa","aaa","aaaa"] 输出: 0 解释: 不存在这样的两个单词。
my solution (slower)
1 | class Solution: |
a faster solution
1 | class Solution: |
初始时有 n 个灯泡关闭。 第 1 轮,你打开所有的灯泡。 第 2 轮,每两个灯泡你关闭一次。 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。第 i 轮,每 i 个灯泡切换一次开关。 对于第 n 轮,你只切换最后一个灯泡的开关。 找出 n 轮后有多少个亮着的灯泡。
示例:
输入: 3 输出: 1 解释: 初始时, 灯泡状态 [关闭, 关闭, 关闭]. 第一轮后, 灯泡状态 [开启, 开启, 开启]. 第二轮后, 灯泡状态 [开启, 关闭, 开启]. 第三轮后, 灯泡状态 [开启, 关闭, 关闭]. 你应该返回 1,因为只有一个灯泡还亮着。
思路:由题意可以知道,一个开关i被拨动的次数就是i的约数的个数,而一个数的约数总是成双成对出现的,除非它是一个完全平方数。约数个数为奇数的情况下,灯是开着的,所以题目就变成求1-n中完全平方数的数目。
1 | import math |
给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。
求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。
说明: 请尽可能地优化你算法的时间和空间复杂度。
示例 1:
输入: nums1 = [3, 4, 6, 5] nums2 = [9, 1, 2, 5, 8, 3] k = 5 输出: [9, 8, 6, 5, 3]
示例 2:
输入: nums1 = [6, 7] nums2 = [6, 0, 4] k = 5 输出: [6, 7, 6, 0, 4]
示例 3:
输入: nums1 = [3, 9] nums2 = [8, 9] k = 3 输出: [9, 8, 9]
思路:
1 | class Solution(object): |
常用的进程间通信方式包括:管道、 消息队列、共享
内存、信号量、套接字等 。其中,前面 4种主要用于同1 台机器上的进程间通信,而套接字
则主要用于不同机器之间的网络通信 。
管道是 Linux 支持的最初
UNIX IPC 形式之一,具有以下特点:
利用管道进行通信: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#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
int fd[2];
pid_t pid;
char buf[256];
int returned_count;
pipe(fd);//创建无名管道
pid = fork();//创建子进程
if(pid < 0)
{
printf("error in fork\n");
exit(1);
}
else if(pid == 0)
{
//child process
printf("in child process...\n");
close(fd[0]);//child process write to parent process,close read pipe
write(fd[1],"hello world",strlen("hello world"));
exit(0);
}else{
//parent process
close(fd[1]);
returned_count = read(fd[0],buf,sizeof(buf));
printf("%d bytes of data received from child process:%s\n",returned_count,buf);
}
return 0;
}
消息队列用于运行于同一台机器上的进程间通信,它和管道很相似,是一个在系统内核
中用来保存消息的队列,它在系统内核中是以消息链表的形式出现 消息链表中节点的结构
msg 声明
共享内存就是允许两个不相关的进程访问同 1个逻辑内存。 共享 内存是在两
个正在运行的进程之间共享和传递数据的非常有效的方式。 不同进程之间共享的内存通
常安排在同1 段物理内存中。 进程可以将同一段共享内存连接到它们 自己 的地址空间中,所
有进程都可以访问共享内存中的地址。
而如果某个进程向共享内存写入数据,所做的改动将影响共享
内存的任何其他进程。
不过,共享内存并未提供同步机制,所以通常需要其他的机制来同步对共享内存的访问。
利用共享内存进行通信:
producer.cpp1
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#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/shm.h>
#include "shm_com.h"
int main()
{
int shmid;
shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);
if(shmid == -1)
{
fprintf(stderr,"shmget failed\n");
exit(EXIT_FAILURE);
}
void *shared_memory = NULL;
shared_memory = shmat(shmid,NULL,0);
if(shared_memory == (void *)-1)
{
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE);
}
printf("memory attached at %X\n",(long)shared_memory);
struct shared_use_st *shared_stuff;
shared_stuff = (struct shared_use_st*)shared_memory;
int running = 1;
char buffer[TEXT_SZ];
while(running)
{
while(shared_stuff->written == 1)
{
sleep(1);
printf("waiting for client...\n");
}
printf("enter some text: ");
fgets(buffer,TEXT_SZ,stdin);
strncpy(shared_stuff->text,buffer,TEXT_SZ);
shared_stuff->written = 1;
if(strncmp(shared_stuff->text,"end",3) == 0)
{
running = 0;
}
}
if(shmdt(shared_memory) == -1)
{
fprintf(stderr,"shmdt failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
consumer.cpp1
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#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/shm.h>
#include "shm_com.h"
int main()
{
int shmid;
srand((unsigned int)getpid());
shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);
if(shmid == -1)
{
fprintf(stderr,"shmget failed\n");
exit(EXIT_FAILURE);
}
void *shared_memory = NULL;
shared_memory = shmat(shmid,NULL,0);
if(shared_memory == (void *)-1)
{
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE);
}
printf("memory attached at %X\n",(long)shared_memory);
struct shared_use_st *shared_stuff;
shared_stuff = (struct shared_use_st*)shared_memory;
shared_stuff->written = 0;
int running = 1;
while(running)
{
if(shared_stuff->written)
{
printf("you wrote:%s",shared_stuff->text);
sleep(rand()%4);
shared_stuff->written = 0;
if(strncmp(shared_stuff->text,"end",3) == 0)
{
running = 0;
}
}
}
if(shmdt(shared_memory) == -1)
{
fprintf(stderr,"shmdt failed\n");
exit(EXIT_FAILURE);
}
if(shmctl(shmid,IPC_RMID,0) == -1)
{
fprintf(stderr,"shmctl failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
头文件shm_com.h1
2
3
4
5
6#define TEXT_SZ 2048
struct shared_use_st{
int written;
char text[TEXT_SZ];
};
#define NULL (void *)0
多线程同步中提及了信号 ,但用于多线程同步的信号量是
POSIX 信号 ,而此信号量是 SYSTEM 信号 ,本质上说这两种都是用户态进
程可以使用的信号量 。
共享内存是进程间通信的最快的方式,但是共享内存的同步问题自身无法解决(即进程该何时去共享内存取得数据,而何时不能取),但用信号量即可轻易解决这个问题。
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
示例 1:
输入: coins = [1, 2, 5], amount = 11 输出: 3 解释: 11 = 5 + 5 + 1
示例 2:
输入: coins = [2], amount = 3 输出: -1
说明:
你可以认为每种硬币的数量是无限的。
1 | class Solution(object): |
1 | class Solution(object): |
给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]… 的顺序。
示例 1:
输入: nums = [1, 5, 1, 1, 6, 4] 输出: 一个可能的答案是 [1, 4, 1, 5, 1, 6]
示例 2:
输入: nums = [1, 3, 2, 2, 3, 1] 输出: 一个可能的答案是 [2, 3, 1, 3, 1, 2]
1 | import time |
给定一个整数数组 nums
,返回区间和在 [lower, upper]
之间的个数,包含 lower
和 upper
。
区间和 S(i, j)
表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。
说明:
最直观的算法复杂度是 O(n2) ,请在此基础上优化你的算法。
示例:
输入: nums = [-2,5,-1], lower = -2, upper = 2, 输出: 3 解释: 3个区间分别是: [0,0], [2,2], [0,2],它们表示的和分别为: -2, -1, 2。
1 | class Solution(object): |
1 | class Solution { |