【LeetCode997】【哈希表】[Py/C#/Scala/Elixir/Kotlin/Rust/Ruby/Swift/PHP/Java/Go/C++/TS/Erlang/Racket/Dart] 一道统计入度出度的简单题目
可以看到,一般而言,Python最接近"想思路时写的伪代码"
目录
解题思路
一道统计入度出度的简单题目
题解地址 https://leetcode.cn/problems/find-the-town-judge/solution/python-by-yhm138_-yezp/
lc997
代码
python3
## 练习使用collections模块的Counter
from collections import Counter
class Solution:
def findJudge(self, n: int, trust: List[List[int]]) -> int:
tmp1=map(lambda x:x[0],trust)
outDgree=Counter(tmp1)
tmp2=map(lambda x:x[1],trust)
inDgree=Counter(tmp2)
for i in range(1,n+1,1):
if inDgree[i]==n-1 and outDgree[i]==0:
return i
return -1
C#
//熟练掌握Dictionary常用API
using System.Collections.Generic;
public class Solution {
public int FindJudge(int n, int[][] trust) {
Dictionary<int,int>inDegree=new Dictionary<int,int>();
Dictionary<int,int>outDegree=new Dictionary<int,int>();
trust.Where((ele, index) =>
{
//Your Logic starts here
if(!inDegree.ContainsKey(ele[1])){
inDegree.Add(ele[1],1);
}
else{
inDegree[ele[1]]+=1;
}
if(!outDegree.ContainsKey(ele[0])){
outDegree.Add(ele[0],1);
}
else{
outDegree[ele[0]]+=1;
}
//Your Logic ends here
return false;
}).Any();
for(int i=1;i<=n;i++){
if(!inDegree.ContainsKey(i)){
inDegree[i]=0;
}
if(!outDegree.ContainsKey(i)){
outDegree[i]=0;
}
if(inDegree[i]==n-1 && outDegree[i]==0 ) return i;
}
return -1;
}
}
scala
import scala.collection.mutable._
//统计入度出度,找到第一个满足【inDegrees[i] == n - 1 && outDegrees[i] == 0】的节点,返回标号i
//这里没有用函数式编程范式
object Solution {
def findJudge(n: Int, trust: Array[Array[Int]]): Int = {
var inDegree=Map[Int,Int]().withDefaultValue(0);
var outDegree=Map[Int,Int]().withDefaultValue(0);
trust.foreach(x=>{
inDegree(x(1))=inDegree.getOrElse(x(1),0)+1;
outDegree(x(0))=outDegree.getOrElse(x(0),0)+1;
});
for(i<- 1 to n){
if(inDegree(i)==n-1 && outDegree(i)==0){
return i;
}
}
-1;
}
}
elixir
# 感谢hexdocs.pm/elixir文档的帮助,我能写出来这份代码很大程度上归功于这份文档写得很详细
# 可以看到我的代码风格,能用API解决的绝不去写模式匹配
defmodule Solution do
@spec find_judge(n :: integer, trust :: [[integer]]) :: integer
def find_judge(n, trust) do
inDegree=trust|> Enum.map(fn x->Enum.at(x,1) end) |> Enum.frequencies()
outDegree=trust|> Enum.map(fn x->Enum.at(x,0) end) |> Enum.frequencies()
ans=(1..n)|> Enum.find(fn x->
# IO.inspect(inDegree)
# IO.inspect(outDegree)
( (n===1 && inDegree[x]===nil)|| (inDegree[x]===n-1) ) && outDegree[x]===nil
end )
# IO.inspect(inDegree)
if (ans===nil) do -1 else ans end
end
end
kotlin
//JVM语言写起来都差不多
//这个我花了几分钟就写完了
class Solution {
fun findJudge(n: Int, trust: Array<IntArray>): Int {
var inDegree = linkedMapOf<Int,Int>();
var outDegree = linkedMapOf<Int,Int>();
var key=-1;
for(i in 0..trust.size-1){
key=trust[i][0];
outDegree[key]=outDegree.getOrDefault(key,0)+1;
key=trust[i][1];
inDegree[key]=inDegree.getOrDefault(key,0)+1;
}
for(i in 1..n){
if (inDegree.getOrDefault(i,0)==n-1 && outDegree.getOrDefault(i,0)==0){
return i;
}
}
return -1;
}
}
rust
// 就是把别人的Rust题解改成HashMap版本的
// 执行用时:24 ms, 在所有 Rust 提交中击败了33.33%的用户
// 内存消耗:2.8 MB, 在所有 Rust 提交中击败了41.67%的用户
use std::collections::HashMap;
impl Solution {
pub fn find_judge(n: i32, trust: Vec<Vec<i32>>) -> i32 {
let mut inDegree =HashMap::new();
let mut outDegree =HashMap::new();
for t in trust{
*inDegree.entry(t[1]).or_insert(0) += 1;
*outDegree.entry(t[0]).or_insert(0) += 1;
}
// println!("{:?}", inDegree);
// println!("{:?}", outDegree);
let my_vec:Vec<_> = (0..=n).step_by(1).collect();
// println!("{:?}", my_vec);
match my_vec.iter().skip(1).position( |&x|
(inDegree.get(&x).cloned().unwrap_or(0)==n-1 && outDegree.get(&x).cloned().unwrap_or(0)==0)
){
Some(i) => i as i32 + 1,
None => -1,
}
}
}
ruby
# @param {Integer} n
# @param {Integer[][]} trust
# @return {Integer}
def find_judge(n, trust)
inDegree = Hash.new(0) #缺省value是0
outDegree = Hash.new(0) #缺省value是0
trust.each_with_index do |t|
inDegree[t[1]]+=1
outDegree[t[0]]+=1
end
for i in 1..n
if(inDegree[i]==n-1 && outDegree[i]==0) then return i end
end
return -1
end
# 下面是草稿
# tmp1 = trust.map do |n|
# n[0]
# end
# puts tmp1
# tmp2=trust.map { |item| item[1]}
# puts "#{index}. #{fruit}"
swift
// import Cocoa //我瞎写的,Cocoa是OS X和 iOS操作系统的程序的运行环境。
class Solution {
func findJudge(_ n: Int, _ trust: [[Int]]) -> Int {
var inDegree = [Int: Int]();
var outDegree = [Int: Int]();
for (index, ele) in trust.enumerated() {
// print("\(index):\(ele)");
inDegree[ele[1],default: 0]+=1;
outDegree[ele[0],default: 0]+=1;
}
for i in 1...n {
if (inDegree[i,default: 0]==n-1 && outDegree[i,default: 0]==0 ) {
return i;
}
}
return -1;
}
}
php
// $符号也太多了,比shell编程用到的$符号还多
class Solution {
/**
* @param Integer $n
* @param Integer[][] $trust
* @return Integer
*/
function findJudge($n, $trust) {
// $inDegree=array();
// $outDegree=array();
$inDegree=array_count_values(array_map(fn($x):int => $x[1] , $trust));
$outDegree=array_count_values(array_map(fn($x):int => $x[0] , $trust));
// var_dump($inDegree);
for ($x=1; $x<=$n; $x++) {
if($inDegree[$x]==$n-1 && $outDegree[$x]==0 ) return $x;
}
return -1;
}
}
//草稿
// print_r(array_map(fn($value): int => $value * 2, range(1, 5)));
java
//这份代码写得确实不好,抱歉
import java.util.*;
public class Solution {
public int findJudge(int n, int[][] trust) {
Map < Integer, Integer > inDegree = new LinkedHashMap < Integer, Integer > ();
Map < Integer, Integer > outDegree = new LinkedHashMap < Integer, Integer > ();
for(int [] ele:trust){
Integer key1=Integer.valueOf(ele[1]);
inDegree.put(key1,inDegree.getOrDefault(key1,0)+1);
Integer key2=Integer.valueOf(ele[0]);
outDegree.put(key2,outDegree.getOrDefault(key2,0)+1);
}
for(int i=1;i<=n;i++){
if(inDegree.getOrDefault(i,0)==n-1 && outDegree.getOrDefault(i,0)==0 ){
return i;
}
}
return -1;
}
}
//下面是草稿
// import java.util.ArrayList;
// import java.util.List;
// import java.util.function.BiConsumer;
// import java.util.function.Consumer;
// import java.util.ArrayList;
// import java.util.Arrays;
// import java.util.stream.Collectors;
// //大佬写的工具类
// class LambadaToolsa {
// /**
// * 利用BiConsumer实现foreach循环支持index
// *
// * @param biConsumer
// * @param <T>
// * @return
// */
// public static <T> Consumer<T> forEachWithIndex(BiConsumer<T, Integer> biConsumer) {
// /*这里说明一下,我们每次传入forEach都是一个重新实例化的Consumer对象,在lambada表达式中我们无法对int进行++操作,
// 我们模拟AtomicInteger对象,写个getAndIncrement方法,不能直接使用AtomicInteger哦*/
// class IncrementInt{
// int i = 0;
// public int getAndIncrement(){
// return i++;
// }
// }
// IncrementInt incrementInt = new IncrementInt();
// return t -> biConsumer.accept(t, incrementInt.getAndIncrement());
// }
// }
golang
//在golang中练习字典用法,写得略丑,抱歉
//golang中变量定义了就要使用,不然编译阶段就会报错
//golang的 }else 在同一行,else不能新起一行
//golang中没有while 应该这么写: for count < 100 { }
import (
"fmt"
);
func findJudge(n int, trust [][]int) int {
var inDegree= make(map[int]int);
var outDegree= make(map[int]int);
for _,ele :=range trust{
if _,ok := inDegree[ele[1]];ok{
inDegree[ele[1]]+=1;
}else{
inDegree[ele[1]]=1;
}
if _,ok := outDegree[ele[0]];ok{
outDegree[ele[0]]+=1;
}else{
outDegree[ele[0]]=1;
}
}
for i:=1;i<=n;i++{
if _,ok := inDegree[i];!ok{
inDegree[i]=0;
}
if _,ok := outDegree[i];!ok{
outDegree[i]=0;
}
if outDegree[i]==0 && inDegree[i]==n-1 {
return i;
}
}
return -1;
}
cpp
//瞎写的,这份代码挺不安全的,最好不要将这样的代码用在你的业务中
//Don't use operator[] with the STL map containers. They construct the value if it is not present.
//Use .at() ,if not present, it will throw exception
using i64 = long long;
constexpr i64 inf = 1E18;
class Solution {
public:
int findJudge(int n, vector<vector<int>>& trust) {
std::unordered_map<int, int> inDegree,outDegree;
for(const auto &t : trust ){
inDegree[t[1]]+=1;
outDegree[t[0]]+=1;
}
for(int i=1;i<=n;i++){
if (inDegree[i]==n-1 && outDegree[i]==0){
return i;
}
}
return -1;
}
};
//下面是一些草稿
// std::vector<int> s1;
// auto addTwoElement = [&](int l,int r) {
// s1.push_back(l);
// s1.push_back(r);
// };
// addTwoElement(3,5);
// for (auto ele : s1) std::cout << ele << ' ';
typescript
//TS是JavaScript的超集,具有可选的类型并可以编译为纯js。从技术上讲TypeScript就是具有静态类型的 JavaScript 。
//注意运算符优先级,这里我被坑了一下 ?? == = + 这些运算符的优先级你知道吗?
function findJudge(n: number, trust: number[][]): number {
let inDegree : {[key:number]:number} = {};
let outDegree : {[key:number]:number} = {};
trust.forEach( (ele,index)=>{
outDegree[ele[0]]=(outDegree[ele[0]]??0)+1;
inDegree[ele[1]]=(inDegree[ele[1]]??0)+1;
});
// console.log(outDegree[1]);
// console.log(outDegree['1']);
const One2n_Range=Array.from(Array(n).keys()).map(x=>1*x+1); //我没找到Range
for(let x of One2n_Range){
if( ((outDegree[x]??0)==0) && ((inDegree[x]??0)==n-1) ){
return x;
}
}
return -1;
};
erlang
%怎么折磨编程菜鸟,给他为数不多的资料,让他持续写3~5小时的Erlang
%这份代码2022-06-24我提交的时候是双百,,,
%可能写Erlang的真的不多,几乎就是纯粹的FP,写各种模式匹配
tally([]) -> [];
tally(L) -> compress2(lists:sort(L)).
compress2([]) -> [];
compress2([H|T]) ->
helper2(T, H, 1).
helper2([H|T], H, Count) ->
helper2(T, H, Count+1);
helper2([H|T], C, Count) ->
[{C, Count}|helper2(T, H, 1)];
helper2([], C, Count) ->
[{C, Count}].
-spec find_judge(N :: integer(), Trust :: [[integer()]]) -> integer().
find_judge(N, Trust) ->
Fun0=fun(V1) -> lists:nth(1,V1) end,
Tmp1=lists:map(Fun0,Trust),
OutDegree=orddict:from_list(tally(Tmp1)),
Fun1=fun(V1) -> lists:nth(2,V1) end,
Tmp2=lists:map(Fun1,Trust),
InDegree=orddict:from_list(tally(Tmp2)),
% io:write(tally([3,4,3,4,3])),
% io:write(InDegree),
% io:write(OutDegree),
case lists:dropwhile(fun(X) ->
% io:write(X),
% io:write(orddict:find(X,InDegree)),
% io:write(orddict:find(X,OutDegree)),
% a=orddict:find(X,InDegree),
% b=orddict:find(X,OutDegree),
not(
(
( orddict:find(X,InDegree)=/=error andalso lists:nth(2,tuple_to_list(orddict:find(X,InDegree)))==N-1 ) or
( orddict:find(X,InDegree)=:=error andalso N==1)
)andalso
(orddict:find(X,OutDegree)=:=error)
)
end, lists:seq(1,N,1)) of
[] -> -1;
[X | _] -> X
end.
%草稿
% Fun0=fun(K,V1) -> lists:nth(1,V1) end,
% Tmp1=maps:map(Fun0,Trust),
% io:write(Tmp1).
racket
; Racket是在基于Scheme发展起来的,当然也是Lisp的一种方言。
; 下面的代码并不是纯粹的FP 可以看到我`hash-set!` 和 `set!` 满天飞
; 怎么折磨写MATLAB数圆括号的人? 让TA来写Racket
; expected a procedure that can be applied to arguments 是因为你使用了冗余的圆括号
; 那什么,,,2022-06-30这份AC代码的执行用时和内存消耗都是33.33%
; 我这份Racket代码确实没有题解区的另外2份Racket代码写得好
(define/contract (find-judge N trust)
(-> exact-integer? (listof (listof exact-integer?)) exact-integer?)
(define (func0 my_list) (list-ref my_list 0))
(define (func1 my_list) (list-ref my_list 1))
(define tmp0 make-list)
(define tmp1 make-list)
(set! tmp0 (map func0 trust))
(set! tmp1 (map func1 trust))
; (displayln tmp0)
(define inDegree (make-hasheq))
(for ([i (in-range 1 (add1 N))]) (hash-set! inDegree i 0) )
(define outDegree (make-hasheq))
(for ([i (in-range 1 (add1 N))]) (hash-set! outDegree i 0) )
(for-each
(lambda (ele) (
hash-set! outDegree ele (+ (hash-ref outDegree ele) 1)
))
tmp0)
(for-each
(lambda (ele) (
hash-set! inDegree ele (+ (hash-ref inDegree ele) 1)
))
tmp1)
; (displayln outDegree)
(define x -1)
(for ([i (in-range 1 (add1 N))])
(
cond([ and (= (- N 1) (hash-ref inDegree i)) (= 0 (hash-ref outDegree i)) ]
(set! x i)
)
)
)
(cond [(= -1 x) -1] [else x]) ;废话大师
)
dart
//写起来和TS,js差不多
class Solution {
int findJudge(int n, List<List<int>> trust) {
var inDegree = new Map();
var outDegree = new Map();
trust.forEach((x){
inDegree[x[1]]=(inDegree[x[1]]??0)+1;
outDegree[x[0]]=(outDegree[x[0]]??0)+1;
});
for(var i=1;i<=n;i++){
if((inDegree[i]??0)==n-1 && (outDegree[i]??0)==0){
return i;
}
}
return -1;
}
}
各语言执行用时和内存消耗比较
我看了下提交记录,Scala最慢,,,Rust(和Java)最快,,,符合预期