第 194 场力扣周赛题解

气死了啊,最后一题下标打错了,发现后已经来不及了。。。。。不过内推场能打到这个名次也还行。可是真的好可惜。

5440. 数组异或操作

思路:按照题目要求直接异或就ok

class Solution {
    public int xorOperation(int n, int start) {
    	
    	int ans=0;
    	
    	for(int i=0;i<n;i++)
    		ans^=start+2*i;
    	
    	return ans;
    	
    }
}

5441. 保证文件名唯一

思路:对于每一种文件名,将名称和次数组成映射即可。

坑点:有可能一个文件名+(文件次数)构造出来的名称已经出现过,这里需要处理一下!

class Solution {
    public String[] getFolderNames(String[] names) {
    	
    	int n=names.length;
    	String[] ans=new String[n];
    	Map<String,Integer> map=new HashMap<>();
    	
    	for(int i=0;i<n;i++) {
    		String s=names[i];
    		if(map.containsKey(s)) {
    			int num=map.get(s)+1;
    			String ss=s+"("+String.valueOf(num)+")";
    			while(map.containsKey(ss)) {
    				num++;
    				ss=s+"("+String.valueOf(num)+")";
    			}
    			ans[i]=ss;
    			map.put(s, num);
    			map.put(ss, 0);
    		}
    		else {
    			ans[i]=s;
    			map.put(s, 0);
    		}
    	}
    	
    	return ans;
    
    }
}

5442. 避免洪水泛滥

PS:这道题当时卡了不少人,我过完这道题后的排名是第13。。

思路:对于每一个rains[i]大于0的位置我们是不用管的,直接无脑输出-1即可,对于rains[i]=0的位置我们需要考虑这个应该抽干哪一个湖泊,可以肯定的是如果有湖泊有产生洪水的风险,我们必须要提前抽干,但是为了保证最后尽可能的不产生洪水,我们对于每一个已经填满的湖泊,若之后他在某一天会下雨,则我们要选择当前天之后最近的一天选择去抽干该湖泊。

class Solution {
    public int[] avoidFlood(int[] rains) {
    	
    	int n=rains.length;
    	int[] ans=new int[n];
    	TreeSet<Integer> st=new TreeSet<>();
    	Map<Integer,Integer> map=new HashMap<>();
    	
    	for(int i=0;i<n;i++) {
    		if(rains[i]>0) {
    			ans[i]=-1;
    			if(map.containsKey(rains[i])) {
    				if(st.isEmpty())
    					return new int[0];
    				else {
    					Integer p=st.higher(map.get(rains[i]));
    					if(p==null) return new int[0];
    					else {
    						ans[(int)p]=rains[i];
    						st.remove(p);
    					}
    				}
    			}
    			map.put(rains[i], i);
    		}
    		else
    			st.add(i);
    	}
    	
    	Iterator<Integer> it=st.iterator();
    	while(it.hasNext())
    		ans[(int)it.next()]=1;
    	
    	return ans;
    	
    }
}

5443. 找到最小生成树里的关键边和伪关键边

思路:这道题真的好气啊,几乎是裸的最小生成树,对于关键边的判定,我们考虑枚举删除那条边会使得最小生成树的值变大;而对于伪关键边,我们在生成最小生成树前,先无脑加入该边,若产生的最小生成树的成本不改变,则这条边为伪关键边。

坑点:在关键边的判定中,删边操作可能会使得最后无法产生最小生成树,因此需要特判一下。

class Solution {
	
	private int[] f;
	private List<node> list;
	private boolean mark;
	class node implements Comparable<node>{
		int id,u,v,val;
		public node(int u,int v,int val) {
			this.u=u;
			this.v=v;
			this.val=val;
		}
		@Override
		public int compareTo(node o) {
			// TODO 自动生成的方法存根
			return val-o.val;
		}
	}
	
	public List<List<Integer>> findCriticalAndPseudoCriticalEdges(int n, int[][] edges) {

		int val=0;
		f=new int[n];
    	list=new ArrayList<>();
    	List<List<Integer>> ans=new ArrayList<>();
    	
    	for(int i=0;i<2;i++)
    		ans.add(new ArrayList<>());
    	
    	for(int i=0;i<edges.length;i++) {
    		list.add(new node(edges[i][0],edges[i][1],edges[i][2]));
    		list.add(new node(edges[i][1],edges[i][0],edges[i][2]));
    	}
    	
    	val=MST(n,-1);
    	int index=edges.length-1;
    	
    	for(int i=list.size()-1;i>0;i-=2) {
    		
    		list.remove(i);
    		list.remove(i-1);
    		mark=false;
    		int now=MST(n,-1);
    		if(val<now || mark) ans.get(0).add(index);
    		list.add(new node(edges[index][0],edges[index][1],edges[index][2]));
    		list.add(new node(edges[index][1],edges[index][0],edges[index][2]));
    		index--;
    	}
    	
    	list.clear();
    	
    	for(int i=0;i<edges.length;i++) {
    		list.add(new node(edges[i][0],edges[i][1],edges[i][2]));
    		list.add(new node(edges[i][1],edges[i][0],edges[i][2]));
    	}
    	
    	index=0;
    	
    	for(int i=0;i<list.size();i+=2) {
    		
    		if(ans.get(0).contains(index)) {
    			index++;
    			continue;
    		}

    		int now=MST(n,index);
    		if(val==now) ans.get(1).add(index);
    		index++;
    	}
    	
    	return ans;
    }
	
	private int MST(int n,int index) {
		
		index=index*2;
		
		List<node> nowList=new ArrayList<>();
		
		int size=list.size(),sum=0,num=0;
		
		int t1,t2;
		
		for(int i=0;i<size;i++)
			nowList.add(list.get(i));
		
		for(int i=0;i<n;i++) f[i]=i;
		
		if(index>=0) {
			t1=find(list.get(index).u);
			t2=find(list.get(index).v);
			if(t1!=t2) {
				num++;
				sum+=list.get(index).val;
				//System.out.println(t1+" "+t2+" "+index+" "+sum);
				f[t1]=t2;
			}
		}
		
		Collections.sort(nowList);
		
		for(int i=0;i<size;i++) {
			t1=find(nowList.get(i).u);
			t2=find(nowList.get(i).v);
			if(t1!=t2) {
				num++;
				sum+=nowList.get(i).val;
				f[t1]=t2;
			}
		}
		
		if(num<n-1) mark=true;
		
		return sum;
	}
	
	private int find(int x) {
		if(f[x]==x)
			return x;
		return f[x]=find(f[x]);
	}
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述: 给出两个非空链表来表示两个非负整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 您可以假设除了数字 0 之外,这两个数都不会以零开头。 示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 解题思路: 题目中要求我们按照逆序的方式存储两个非负整数,也就是说链表的头节点表示该数的个位,第二个节点表示该数的十位,以此类推。 因此,我们可以从两个链表的头节点开始,对应位相加,并记录进位,将结果添加到新的链表中。如果有进位,需要在下一位相加时加上进位。 需要注意的是,当两个链表的长度不一致时,可以将较短的链表的缺失位看作是 0。 最后,如果最高位有进位,还需要在新链表的最高位添加一个值为 1 的节点。 C 语言代码实现: /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){ struct ListNode *head = NULL, *tail = NULL; int carry = 0; while (l1 || l2) { int n1 = l1 ? l1->val : 0; int n2 = l2 ? l2->val : 0; int sum = n1 + n2 + carry; if (!head) { head = tail = malloc(sizeof(struct ListNode)); tail->val = sum % 10; tail->next = NULL; } else { tail->next = malloc(sizeof(struct ListNode)); tail = tail->next; tail->val = sum % 10; tail->next = NULL; } carry = sum / 10; if (l1) l1 = l1->next; if (l2) l2 = l2->next; } if (carry > 0) { tail->next = malloc(sizeof(struct ListNode)); tail = tail->next; tail->val = carry; tail->next = NULL; } return head; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值