不得不说 leetCode 比ACM 温和多了,很适合退役ACMer选手,居然我也能AK比赛,当然代码还是有点挫的,比不了手速大佬18 mins AK。
比赛链接(PS: 如果你也对此比赛感兴趣,不妨联系我,每周一起打结个伴…. email: [email protected])
official solution
这个很简单,按照题意模拟就可….
时间复杂度( O(∑|Si|) )
My code
class Solution {
private boolean isVowel(char c) {
c = Character.toLowerCase(c);
return c =='a' | c =='e'|c=='i'|c=='o'|c=='u';
}
public String toGoatLatin(String S) {
String[] tmp = S.split(" ");
StringBuilder ap = new StringBuilder("a");
StringBuilder ret = new StringBuilder();
for(String e : tmp){
StringBuilder x = new StringBuilder();
if(isVowel(e.charAt(0))){
x.append(e);
}else{
x.append(e.substring(1)+e.charAt(0));
}
x.append("ma");
x.append(ap);
ap.append("a");
ret.append(x);
ret.append(" ");
}
return ret.substring(0, ret.length()-1);
}
}
直接记录每种 cnt[i] : ∑ages[j]==i ,
可以发现不满足friend
的条件是一样的,我们可以整合一下它给出的3个条件
对于 age=A 的人来说,我们需要减去,这些值:
mycode
class Solution {
public int numFriendRequests(int[] ages) {
int[] cnt = new int[121];
int ma = 0;
for(int i=0 ; iint[] sum = new int[ma+1];
sum[0] =0;
for(int i=1 ; i<=ma ; ++i)
sum[i] = sum[i-1]+cnt[i];
int ret =0;
for(int i=1 ; i<=ma ; ++i){
int val = ages.length;
val -= sum[ma] - sum[i];
int lower = Math.min((int)(0.5*i+7), i);
val -= sum[lower];
--val;
ret += Math.max(0, val) * cnt[i];
}
return ret;
}
}
这题的贪心思想都烂大街了,比一般的贪心要简单,因为worker
是独立的
直接按照 difficulty
对 job pai排序,然后对 worker
排序, 要求的答案相当于是, ∑jmaxdiffi≤workerj{profiti} , 由于是递增的直接用一个pointer
维护当前的job,记录 maxProfit 就好
时间复杂度 :O( n )
my code
class Solution {
class Node{
int dif,prf;
public Node(int dif, int prf) {
super();
this.dif = dif;
this.prf = prf;
}
}
public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
Node[] a = new Node[profit.length];
for(int i=0 ; inew Node(difficulty[i], profit[i]);
Arrays.sort(a, new Comparator() {
@Override
public int compare(Node o1, Node o2) {
// TODO Auto-generated method stub
return o1.dif - o2.dif;
}
});
int ret =0;
int j = 0;
Arrays.sort(worker);
int mxprf =0;
for(int i=0 ; iwhile (jreturn ret;
}
}
这个题,我yy了一下,没想到居然过了….
首先 grid[n][m]
n,m<=50
我们可以求出联通集合及其大小:
O( nm )
然后因为每次修改一个点,所以我们可以简单的对每一个 grid[i][j]=0 的点测试,计算修改它后的最大值,具体来说:
对其4联通点,将其联通集元素个数相加
mycode
class Solution {
int[][] map;
class Helper{
int n,m;
boolean[][] vis;
int[][] beto;
int[] unVal;
int ans;
public Helper(int n, int m) {
super();
this.n = n;
this.m = m;
unVal = new int[n*m+10];
beto = new int[n][m];
Arrays.fill(unVal, 0);
this.vis = new boolean[n][m];
for(int i=0 ; ifor(int j=0 ; jfalse;beto[i][j]=0;
}
}
private boolean isLegal(int x,int y) {
return x >=0 &&x < n && y >=0 &&yint[] dx = new int[]{-1,1,0,0};
int[] dy = new int[]{0,0,1,-1};
private void dfs(int ix,int iy,int fa) {
vis[ix][iy] = true;
if(map[ix][iy] == 0)return;
++unVal[fa];
ans = Math.max(ans, unVal[fa]);
beto[ix][iy] =fa;
for(int i=0 ; i<4 ; ++i){
int nx =ix + dx[i];
int ny = iy + dy[i];
if(isLegal(nx, ny) && !vis[nx][ny])dfs(nx, ny, fa);
}
}
private int solve() {
int fa =0;
for(int i=0 ; ifor(int j=0 ; jif(!vis[i][j])dfs(i, j, ++fa);
for(int i=0 ; ifor(int j=0 ; jif(map[i][j] ==0){
int tmp =1;
HashSet num = new HashSet<>();
for(int k=0 ; k<4 ; ++k){
int x= i+dx[k];
int y = j+dy[k];
if(isLegal(x, y)){
num.add(beto[x][y]);
}
}
for(Integer e: num)
tmp+= unVal[e];
ans = Math.max(ans, tmp);
}
}
return ans;
}
}
public int largestIsland(int[][] grid) {
map = grid;
Helper solver = new Helper(grid.length, grid[0].length);
return solver.solve();
}
}