LeetCode 382~388题

第三百八十二题

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* h;

    /** @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node. */
    Solution(ListNode* head) {
        h = head;
    }

    /** Returns a random node's value. */
    int getRandom() {
        int c = -1, n = 0;
        for (auto p = h; p; p = p->next) {
            n ++ ;
            if (rand() % n == 0) c = p->val;
        }
        return c;
    }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* obj = new Solution(head);
 * int param_1 = obj->getRandom();
 */
import java.util.Random;

Class Solution{
    public static void main(String[] args){
        int[] nums = new int[]{1, 2, 3, 4, 5};
        Solution s = new Solution();
        int[] ans = s.sample(nums, 3);
        for(int i = 0; i < ans.length; i++){
            System.out.printf("%d ", ans[i]);
        }
    }
    private int[] sample(int[] nums, int n){
        Random rd = new Random();
        int[] ans = new int[n];
        for(int i = 0; i < nums.length; i++){
            if(i < n){
                ans[i] = nums[i];
            } else {
                if(rd.nextInt(i+1) < n){
                    ans[rd.nextInt(n)] = nums[i];
                }
            }
        }
        return ans;
    }
}
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:

    def __init__(self, head: ListNode):
        """
        @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node.
        """
        self.head = head


    def getRandom(self) -> int:
        """
        Returns a random node's value.
        """
        time = 0 
        p  = self.head
        res = None
        while p:
            time +=1
            if random.randint(1,time)==1:
                res = p.val
            p = p.next
        return res
# Your Solution object will be instantiated and called as such:
# obj = Solution(head)
# param_1 = obj.getRandom()
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
type Solution struct {
    head *ListNode
    r *rand.Rand
}


/** @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node. */
func Constructor(head *ListNode) Solution {
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    solution := Solution{
        head: head,
        r: r,
    }
    return solution
}

/** Returns a random node's value. */
func (this *Solution) GetRandom() int {
    i := 2
    cur := this.head.Next
    val := this.head.Val
    for cur != nil {
        if this.r.Intn(i)+1 == i {
            val = cur.Val
        }
        i++
        cur = cur.Next
    }
    return val
}

### 复杂度分析
时间复杂度:O(n)至少要遍历到n个元素
空间复杂度:O(1)常数空间复杂度

/**
 * Your Solution object will be instantiated and called as such:
 * obj := Constructor(head);
 * param_1 := obj.GetRandom();
 */

第三百八十三题

class Solution {
public:
    bool canConstruct(string a, string b) {
        unordered_map<char, int> hash;
        for (auto c: b) hash[c] ++ ;
        for (auto c: a)
            if (!hash[c]) return false;
            else hash[c] -- ;
        return true;
    }
};
class Solution {
     public boolean canConstruct(String ransomNote, String magazine) {
        char[] chars1 = ransomNote.toCharArray();
        char[] chars2 = magazine.toCharArray();
        if (chars1.length > chars2.length) {
            return false;
        }
        int[] rans = new int[26];
        int[] maga = new int[26];
        for (char c : chars1) {
            rans[c - 'a']++;
        }
        for (char c : chars2) {
            maga[c - 'a']++;
        }
        for (int i = 0; i < rans.length ; i++) {
            if (rans[i] > maga[i]) {
                return false;
            }
        }
        return true;
    }
}
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        hash_table_m = collections.Counter(magazine)
        hash_table_r = collections.Counter(ransomNote)

        """for i in hash_table_r:
            if hash_table_r[i] > hash_table_m[i]:
                return False
        return True"""
        return not hash_table_r - hash_table_m
func canConstruct(ransomNote string, magazine string) bool {
    ransomArray := [26]int{}//信件的所有英文数字的出现次数
    magArray := [26]int{}//统计杂志的所有英文数字的出现次数
    for _,v:= range []rune(ransomNote){
        ransomArray[v-97]++
    }
    for _,v:= range []rune(magazine){
        magArray[v-97]++
    }
    for i:=0;i<26;i++{
        if magArray[i]<ransomArray[i] {return false}
    }
    return true

}
//哈希表

第三百八十四题

class Solution {
public:
    vector<int> a;

    Solution(vector<int>& nums) {
        a = nums;
    }

    /** Resets the array to its original configuration and return it. */
    vector<int> reset() {
        return a;
    }

    /** Returns a random shuffling of the array. */
    vector<int> shuffle() {
        auto b = a;
        int n = a.size();
        for (int i = 0; i < n; i ++ )
            swap(b[i], b[i + rand() % (n - i)]);
        return b;
    }
};
/**
 * Your Solution object will be instantiated and called as such:
 * Solution* obj = new Solution(nums);
 * vector<int> param_1 = obj->reset();
 * vector<int> param_2 = obj->shuffle();
 */
class Solution {
    private int[] array;
    private int[] original;

    Random rand = new Random();

    private int randRange(int min, int max) {
        return rand.nextInt(max - min) + min;
    }

    private void swapAt(int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    public Solution(int[] nums) {
        array = nums;
        original = nums.clone();
    }
    
    public int[] reset() {
        array = original;
        original = original.clone();
        return original;
    }
    
    public int[] shuffle() {
        for (int i = 0; i < array.length; i++) {
            swapAt(i, randRange(i, array.length));
        }
        return array;
    }
}
class Solution:
    def __init__(self, nums):
        self.array = nums
        self.original = list(nums)

    def reset(self):
        self.array = self.original
        self.original = list(self.original)
        return self.array

    def shuffle(self):
        for i in range(len(self.array)):
            swap_idx = random.randrange(i, len(self.array))
            self.array[i], self.array[swap_idx] = self.array[swap_idx], self.array[i]
        return self.array
type Solution struct {
    arr []int
}


func Constructor(nums []int) Solution {
    
    return Solution{nums}
}


/** Resets the array to its original configuration and return it. */
func (this *Solution) Reset() []int {
    return this.arr
}


/** Returns a random shuffling of the array. */
func (this *Solution) Shuffle() []int {
    n := len(this.arr)
    res := make([]int, n)
    copy(res, this.arr)
    for i := n-1; i >= 0; i-- {
        rand := rand.Intn(i+1)    // math.rand中的Intn(i+1)返回[0, i]范围的整数,每次数组在下标index为[0, i]范围内随机找一个下标对应的元素与当前位置i处的元素进行交换
        res[i], res[rand] = res[rand], res[i]   // 对应位置元素交换,也可以使用如下代码
        // tmp := res[i]
        // res[i] = res[rand]
        // res[rand] = tmp
    } 
    return res
}


/**
 * Your Solution object will be instantiated and called as such:
 * obj := Constructor(nums);
 * param_1 := obj.Reset();
 * param_2 := obj.Shuffle();
 */

第三百八十五题

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * class NestedInteger {
 *   public:
 *     // Constructor initializes an empty nested list.
 *     NestedInteger();
 *
 *     // Constructor initializes a single integer.
 *     NestedInteger(int value);
 *
 *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
 *     bool isInteger() const;
 *
 *     // Return the single integer that this NestedInteger holds, if it holds a single integer
 *     // The result is undefined if this NestedInteger holds a nested list
 *     int getInteger() const;
 *
 *     // Set this NestedInteger to hold a single integer.
 *     void setInteger(int value);
 *
 *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
 *     void add(const NestedInteger &ni);
 *
 *     // Return the nested list that this NestedInteger holds, if it holds a nested list
 *     // The result is undefined if this NestedInteger holds a single integer
 *     const vector<NestedInteger> &getList() const;
 * };
 */
class Solution {
public:
    NestedInteger deserialize(string s) {
        int u = 0;
        return dfs(s, u);
    }

    NestedInteger dfs(string& s, int& u) {
        NestedInteger res;
        if (s[u] == '[') {
            u ++ ;  // 跳过左括号
            while (s[u] != ']') res.add(dfs(s, u));
            u ++ ;  // 跳过右括号
            if (u < s.size() && s[u] == ',') u ++ ;  // 跳过逗号
        } else {
            int k = u;
            while (k < s.size() && s[k] != ',' && s[k] != ']') k ++ ;
            res.setInteger(stoi(s.substr(u, k - u)));
            if (k < s.size() && s[k] == ',') k ++ ;  // 跳过逗号
            u = k;
        }
        return res;
    }
};
class Solution {
    //递归函数通过字符数组和cur下标确定要处理的位置
    char[] chars;
    int cur = 0;
    public NestedInteger deserialize(String s) {
        chars = s.toCharArray();
        //本身不是一个集合而是一个整数的情况
        if(chars[0]!='[') return new NestedInteger(Integer.valueOf(s));
        //调用递归函数返回根集合
        return getNest();
    }
    public NestedInteger getNest(){
        NestedInteger nest = new NestedInteger();
        int num = 0;//num用于缓存用逗号分割的整数类型的值
        int sign = 1;//当前记录的整数的符号,1代表整数,-1代表负数
        while(cur!=chars.length-1){
            cur ++;
            if(chars[cur]==',') continue;
            if(chars[cur]=='[') nest.add(getNest());//遇到[递归获取子集合
            else if(chars[cur]==']') return nest;
            else if(chars[cur]=='-') sign = -1;
            else{//是数字的情况
                num = 10*num + sign * (chars[cur]-'0');
                //如果下一个字符是,或者]说明当前数字已经记录完了,需要加入集合中
                if(chars[cur+1]==','||chars[cur+1]==']'){ 
                    nest.add(new NestedInteger(num));
                    num = 0;
                    sign = 1;
                }
            }
        }
        return null;
    }
}
class Solution:
    def deserialize(self, s: str) -> NestedInteger:
        def dfs(elem):
            if type(elem) == int:
                return NestedInteger(elem)
            li = NestedInteger()  # 这个对象为空时是一个空列表
            for i in elem:
                li.add(dfs(i))
            return li

        return dfs(eval(s))

        # empty123 = NestedInteger() #空列表
        # num123=NestedInteger(123)
        # empty123.add(num123)

        # empty456=NestedInteger()#空列表
        # num456=NestedInteger(456)
        # empty456.add(num456)

        # empty123.add(empty456)

        # return empty123
func deserialize(s string) *NestedInteger {
	if s[0] != '[' {
		var ni NestedInteger
		num, _ := strconv.Atoi(s)
		ni.SetInteger(num)
		return &ni
	}
	stack := make([]NestedInteger, 0)
	sign, num, isNum := 1, 0, false
	for _, char := range s {
		//0-9 [ - , ]
		if char == '[' {
			stack = append(stack, NestedInteger{})
		} else if char == ']' {
			if isNum {
				var ni NestedInteger
				ni.SetInteger(sign * num)
				stack[len(stack)-1].Add(ni)
				sign, num, isNum = 1, 0, false
			}
			if len(stack) > 1 {
				pop := stack[len(stack)-1]
				stack = stack[:len(stack)-1]
				/*
					这样写"[[]]"会报错,应该是与Add底层实现有关系
					top := stack[len(stack)-1]
					top.Add(pop)
				*/
				stack[len(stack)-1].Add(pop)
			}
		} else if char == ',' {
			if isNum {
				var ni NestedInteger
				ni.SetInteger(sign * num)
				stack[len(stack)-1].Add(ni)
				sign, num, isNum = 1, 0, false
			}
		} else if char == '-' {
			sign = -1
		} else {
			num = int(char-'0') + num*10
			isNum = true
		}
	}
	return &stack[0]
}

第三百八十六题

class Solution {
public:
    vector<int> res;
    vector<int> lexicalOrder(int n) {
        for (int i = 1; i <= 9; i ++ ) dfs(i, n);
        return res;
    }
    void dfs(int cur, int n) {
        if (cur <= n) res.push_back(cur);
        else return;
        for (int i = 0; i <= 9; i ++ ) dfs(cur * 10 + i, n);
    }
};
class Solution {
    // public List<Integer> lexicalOrder(int n) {
    //     List<Integer> list = new ArrayList<>();
    //     int curr = 1;
    //     //10叉树的先序遍历
    //     for(int i=0;i<n;i++){
    //         list.add(curr);
    //         if(curr*10<=n){
    //             curr*=10;//进入下一层
    //         }else{
    //             if(curr>=n)   curr/=10;//如果这一层结束了
    //             curr+=1;
    //             while(curr%10==0) curr/=10;//如果>10就要返回上一层
    //         }
    //     }
    //     return list;
    // }
    public List<Integer> lexicalOrder(int n) {
        List<Integer> list = new ArrayList<>();
        for (int i = 1; i < 10; i++){
             dfs(n, i, list);
        }
        return list;
    }
    private void dfs(int n,int i,List<Integer>list){
        if(i>n){
            return ;
        }
        list.add(i);
        for(int j=0;j<=9;j++){
            dfs(n,i*10+j,list);
        }
    }

}
class Solution:
    def lexicalOrder(self, n: int) -> List[int]:

        # N叉树 深度优先搜索
        res= []
        def dfs(i):
            cur = i
            if cur >n:
                return
            res.append(cur) 
            for j in range(10):
                dfs(cur*10+j)
        for i in range(1,10):
            dfs(i)
        return res
func lexicalOrder(n int) []int {
	ret := make([]int, 0)
	num := 1
	for {
		if num <= n {
			ret = append(ret, num)
			num *= 10
		} else {
			num /= 10
			for num % 10 == 9 {
				num /= 10
			}
			if num == 0 {
				break
			}
			num++
		}
	}
	return ret
}

第三百八十七题

class Solution {
public:
    int firstUniqChar(string s) {
        unordered_map<char, int> hash;
        for (auto c: s) hash[c] ++ ;
        for (int i = 0; i < s.size(); i ++ )
            if (hash[s[i]] == 1)
                return i;
        return -1;
    }
};
class Solution {
    public int firstUniqChar(String s) {
        Map<Character, Integer> position = new HashMap<Character, Integer>();
        int n = s.length();
        for (int i = 0; i < n; ++i) {
            char ch = s.charAt(i);
            if (position.containsKey(ch)) {
                position.put(ch, -1);
            } else {
                position.put(ch, i);
            }
        }
        int first = n;
        for (Map.Entry<Character, Integer> entry : position.entrySet()) {
            int pos = entry.getValue();
            if (pos != -1 && pos < first) {
                first = pos;
            }
        }
        if (first == n) {
            first = -1;
        }
        return first;
    }
}
class Solution:
    def firstUniqChar(self, s: str) -> int:
        position = dict()
        n = len(s)
        for i, ch in enumerate(s):
            if ch in position:
                position[ch] = -1
            else:
                position[ch] = i
        first = n
        for pos in position.values():
            if pos != -1 and pos < first:
                first = pos
        if first == n:
            first = -1
        return first
func firstUniqChar(s string) int {
    n := len(s)
    pos := [26]int{}
    for i := range pos[:] {
        pos[i] = n
    }
    for i, ch := range s {
        ch -= 'a'
        if pos[ch] == n {
            pos[ch] = i
        } else {
            pos[ch] = n + 1
        }
    }
    ans := n
    for _, p := range pos[:] {
        if p < ans {
            ans = p
        }
    }
    if ans < n {
        return ans
    }
    return -1
}

第三百八十八题

class Solution {
public:
    int lengthLongestPath(string input) {
        stack<int> stk;
        int res = 0;
        for (int i = 0, sum = 0; i < input.size(); i ++ ) {
            int k = 0;
            while (i < input.size() && input[i] == '\t') i ++ , k ++ ;
            while (stk.size() > k) sum -= stk.top(), stk.pop();
            int j = i;
            while (j < input.size() && input[j] != '\n') j ++ ;
            int len = j - i;
            stk.push(len), sum += len;
            if (input.substr(i, len).find('.') != -1)
                res = max(res, sum + (int)stk.size() - 1);
            i = j;
        }
        return res;
    }
};
class Solution {
    public int lengthLongestPath(String input) {
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int ans = 0;
        // 以 \n 分割成字符串数组
        String[] str = input.split("\n");
        // dir,\tsubdir1,\tsubdir2,\tfile.ext
        for (String s : str) {
            // level 代表当前字符串的首字母索引
            // 字符串前面可能会有多个 \t,故使用 lastIndexOf 找出最后一个 \t 位置即可
            int level = s.lastIndexOf("\t") + 1;
            while (level + 1 < stack.size()) {
                stack.pop();
            }
            // 之前入栈的字符串 + 当前遍历到的字符串的长度
            int len = stack.peek() + (s.length() - level + 1);
            stack.push(len);
            if (s.contains(".")) {
                ans = Math.max(ans, len - 1);
            }
        }
        return ans;
    }
}
class Solution:
    def lengthLongestPath(self, input: str) -> int:
        prefixSum = [0]
        res = 0
        for s in input.split('\n'):
            level = 0  # 当前层级
            while s[level] == '\t':
                level += 1
            sLen = len(s) - level
            # 如果是文件,比较最大值。
            if '.' in s:
                res = max(res, prefixSum[level] + sLen)
                continue
            # 如果是文件夹,将当前层级的字符串数目(包含末尾斜杆)保存。
            if level + 1 < len(prefixSum):
                prefixSum[level + 1] = prefixSum[level] + sLen + 1
            else:
                prefixSum.append(prefixSum[-1] + sLen + 1)
        return res
func lengthLongestPath(input string) int {
	s := strings.Split(input, "\n")
	var paths []Path // 所有路径,包括缩进层次和路径
	for _, v := range s {
		level := strings.Count(v, "\t")
		paths = append(paths, Path{v[level:], level})
	}
	var stack []Path
	var result int
	for _, v := range paths {
		// 总是保证栈顶是小于该文件的缩进的
		for len(stack) != 0 && stack[len(stack)-1].Level >= v.Level {
			stack = stack[:len(stack)-1]
		}
		stack = append(stack, v)
		if strings.Contains(v.Content, ".") {
			result = max(result, calLen(stack))
		}
	}
	return result
}

type Path struct {
	Content string
	Level   int
}

func calLen(stack []Path) int {
	result := 0
	for _, v := range stack {
		result += len(v.Content)
	}
	// 多加 len(stack) - 1 个 "/"
	return result + len(stack) - 1
}

func max(num1, num2 int) int {
	if num1 > num2 {
		return num1
	}
	return num2
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能say的秘密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值