每日编程--(三十)

题目:验证栈序列

题目描述:
给定 pushed 和 popped 两个序列,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

分析:就是模拟栈的进栈出栈,大概思路就是,初始化一个切片res,存放进栈元素,初始化一个cnt,标识正确出栈元素的数量,根据不同的情况进行操作,首先如果res不是空的,res的最后一个元素等于出栈的第一个元素,那就将res最后一个元素去掉,cnt++;如果popped[j]==pushed[i],直接不需要进栈,cnt++;最后就是需要进栈的操作了。说的比较不清楚,没关系看代码就好了

代码:

func validateStackSequences(pushed []int, popped []int) bool {
    res:=[]int{}
    cnt:=0
    i:=0
    j:=0
    for j<len(popped){
        if len(res)!=0 && res[len(res)-1]==popped[j]{
            j++
            res=res[:len(res)-1]
            cnt++
        }else if i<len(pushed) && popped[j]==pushed[i]{
            i++
            j++
            cnt++
        }else{
            if i==len(pushed){      
                return false
            }
            res=append(res,pushed[i])
            i++
        }
    }
    if cnt==len(pushed){
        return true
    }
    return false
}

题目:全排列

题目描述:
给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

分析:一开始想的用回溯法,不知道为什么go语言一直出错,后来看了人家的代码,用了递归,大致的意思就是每次选出一个元素作为开头的元素,然后最后只剩一个了,再加上上次选中的,再进行交换,一级一级递推
代码:

func permute(nums []int) [][]int {
    n:=len(nums)
    res:=make([][]int,0)
    if n==0{
        return nil
    }
    if n==1{
        return append(res,[]int{nums[0]})
    }
    for i:=0;i<n;i++{
        swap(&nums[0],&nums[i])
        sans:=permute(nums[1:])
        for _,v:=range sans{
            v=append(v,nums[0])
            L:=len(v)
            for k:=0;k<L/2;k++{
                swap(&v[k],&v[L-1-k])
            }
            res=append(res,v)
        }
        swap(&nums[0],&nums[i])
    }
    return res
    
}
func swap(nums1 ,nums2*int){
    if nums1==nums2{
        return 
    }
    temp:=*nums1
    *nums1=*nums2
    *nums2=temp
}
                      

题目:报数

题目描述:
报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

  1. 1
    
  2. 11
    
  3. 21
    
  4. 1211
    
  5. 111221
    

1 被读作 “one 1” (“一个一”) , 即 11。
11 被读作 “two 1s” (“两个一”), 即 21。
21 被读作 “one 2”, “one 1” (“一个二” , “一个一”) , 即 1211。

给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

注意:整数顺序将表示为一个字符串。

示例 1:

输入: 1
输出: “1”
示例 2:

输入: 4
输出: “1211”、
分析:还是递归,确定的就是1返回的是”1“,然后通过遍历,记录重复次数,遇到不一样的就进行一次拼接,strconv.Itoa(repeatCount),int转换成字符串
代码:



func countBefore(s string) string {
	resStr := ""
	// 本质上是对每个数字用重复次数+重复的数字然后拼起来
	repeatCount := 1
	for i := 0; i < len(s); i++ {
		if i+1 < len(s) && s[i] == s[i+1] {
			// 寻找出现重复的数字,累计重复次数
			// 如果运行到末尾,且末尾不是重复数字的情况也是执行else的逻辑
			// 如果末尾和之前的重复,那么会被repeatCount记录
			repeatCount++
		} else {
			resStr += strconv.Itoa(repeatCount) + string(s[i])
			// 重置重复次数
			repeatCount = 1
		}
	}
	return resStr
}

func countAndSay(n int) string {
	if n == 1 {
		return "1"
	}
	return countBefore(countAndSay(n - 1))
}

题目:压缩字符串

题目描述:
在完成原地修改输入数组后,返回数组的新长度。

进阶:
你能否仅使用O(1) 空间解决问题?

示例 1:

输入:
[“a”,“a”,“b”,“b”,“c”,“c”,“c”]

输出:
返回6,输入数组的前6个字符应该是:[“a”,“2”,“b”,“2”,“c”,“3”]

说明:
"aa"被"a2"替代。"bb"被"b2"替代。"ccc"被"c3"替代。
示例 2:

输入:
[“a”]

输出:
返回1,输入数组的前1个字符应该是:[“a”]

说明:
没有任何字符串被替代。
示例 3:

输入:
[“a”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”]

输出:
返回4,输入数组的前4个字符应该是:[“a”,“b”,“1”,“2”]。

说明:
由于字符"a"不重复,所以不会被压缩。"bbbbbbbbbbbb"被“b12”替代。
注意每个数字在数组中都有它自己的位置。
注意:

所有字符都有一个ASCII值在[35, 126]区间内。
1 <= len(chars) <= 1000。
分析:这道题和上一道题有相似的地方,就是要记录重复字数,需要在原来的切片上进行改动,不能申请额外空间,不多说了,看代码吧,需要注意的就是int转换成byte,我是先转换成string,再转换成byte
代码:

func compress(chars []byte) int {
     count :=1
    if len(chars)==0 || len(chars)==1{
        return len(chars)
    }
    cur:=0
    for i:=1;i<len(chars);i++{
        if chars[i]==chars[cur]{
            count++
        }else{
            if count>1{
              
                str:=strconv.Itoa(count)
                for j:=0;j<len(str);j++{
                    cur++
                    chars[cur]=byte(str[j])
                }
               
                count=1
            }
            cur++
            chars[cur]=chars[i]
        }
    }
    if count>1{
       
                str:=strconv.Itoa(count)
                for j:=0;j<len(str);j++{
                    cur++
                    chars[cur]=byte(str[j])
                }
               
            
    }
    chars=chars[:cur+1]
    return cur+1
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值